Studiekompasset.dkKlasse: HTX 3. år · Fag: Programmering C
HTX 3. år
Programmeringseksamensrapport
OliverNybroe3.Z
EmilRysgaard3.Z
12. maj2015
Vejleder:
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Synopsis
Idennerapportvilvilaveetinkrementaltspil,altsåenspilhvorformåleterattjenepenge
vedatrepeteredensammehandling.Detervoresmålatkonstrueredeetsolidtskelettil
sådanetspil,sådanatmannemtifremtidenvillekunneudvikleyderligeretilføjelsersom:
flerefunktioner,sjovgrafik,lydeffekter.
VihartænktosatlavespilletiprogrammeringssprogetPythonogbr
ugergrænsefladeni
Qt,medetwrappertilPython,altsåsåkodenkanbliveskrevetiPython.Vihartænktosat
kodespillethenholdsvisobjektorienteretoglavedetmultitrådetsådansåvikanudføre
flereoperationersamtidig,udenatspilletfryser.
Spilletvirkerogkanrentfaktiskspilles,menalledeønskedefunktionervilvillehaveer
dogikkeendelafspillet.Heleskelettetpåplads,
ogfåafdevidereudviklingersomvi
havdetænktoserogsåendelafspillet.
OBS!
Foratmankankørervoresprogramermannødttilathavedefølgendeprogrammer
installeret:
Python3.4
PyQt5
Defølgendeprogrammerkanhentespådissetohjemmesider
https://www.python.org/downloads/

http://www.riverbankcomputing.co.uk/software/pyqt/download5
2
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Indholdsfortegnelse
QuestTyper 1
Synopsis
2
Indholdsfortegnelse
3
Hjælptillæsningafrapport
4
Problemformulering
4
Kravspecifikationer
4
Teori
5
Variabler
5
Integer
5
List
5
String
5
Boolean
5
Statements
5
If
5
Forløkker
6
Whileløkker
6
Operatører
6
Funktioner
6
Klasser
6
Objektorienteret
7
Biblioteker
8
Qt
8
WrappersogPyQt
8
Multitrådning
8
Designafbrugergrænseflade
9
Programmeringssprog
10
Flowchart
11
Implementering
12
Testafprogrammet
21
Konklusion
22
Litteraturliste
23
Bilag
24
Voresfuldekode
24
3
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Hjælp til læsning af rapport
Idennerapportvilviformaterealtkodemedfonten“Consolas”istørrelse9ogcursiv,dog
hviskodenkommermidtiensætningvildetblivemarkeretmedgråbaggrund.
VæropmærksompåatførprogrammetskalkøresskalbådePython3.4ogPyQt5være
installeret.(linkstilhentningerisynopsisafsnittet)
Problemformulering
Programmetsformåleratværeetinkrementaltspil.Etinkrementaltspilerentypespil
hvordensammesimplehandlingblivergentagetforattjenepengeogsåbrugermande
pengeforattjeneflerepenge.Voresspilvirkerpåpræcissammemåde,manharfåpenge
tilatstartemedogsåkanmankøbetingsomgørmanfårflerepengepr.sekund.
Vivalgteatlaveetinkrementaltspil,fordivimenteatdetvilleværeenpassende
udfordring
forvoresfærdighederindenforprogrammeringogfordivisynesspilsomdette
erunderholdende.
Kravspecifikationer
Ivoresinkrementalespilforventerviatdefølgendefunktionervirker:
Brugergrænseflade
Spilletskerne(købaftingogtjenpengepådemovertidudfrahvormangeman
harkøbt)
Knapmankantrykkepå,forattjeneenlilleantalpenge.
Hvisvihartidnokogfølerdissefunktion
ervillegavnespilletmeget,vilvigerne
implementeredissefølgendeting:
Multitrådning
Lave8tingmankankøbe
Lavebrugergrænsefladenpænogmereavanceret
Gemoglæsfunktion(save+load)
Mulighedforatsælgeting
Speciellebegivenheder(somingenindkomstførmanklipper20gangepåen
specielting)
Lavikonertiltingenemankankøbe
4
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Teori
TilvoresprogramerderbrugtmangeforskelligefunktioneriPython,hervilvigennemgå
nogleafdefunktionerPythonharoghvaddegør,sådererenforståelseforhvorforvi
vælgeratbrugedissefunktioner,operatørerogvariabeltypernårvigør.
Variabler
Envariableeretsymbolellernavnsomstårforenværdi.Derfindesflereforskelligetyper
afvariablersomallekannogleforsk
elligeting.Variablerbrugestilathavedynamisk
indholdellerforblotatgøreenskodemeresimpeloglettereforståelig.
Integer
Enintegererenvariabelhvordensværdikunkanværeettal.altsåforeksempelA=3
betyderatnårmanskriver
Asåskriverdenrentfaktisk3.
1
List
Enlisteerenvariabeltypesomkanindeholdemereend1værdi,herkanmanhaveen
listeafværdier.Fore
ksempelList = [1, 2, 3, 4].Herkanmansåvælgeatblotatprinte
enafværdierneellerændreenellerflereafværdierne.
String
Stringerenvariabeltypehvorværdienkanværetekst,talogsymboler.Dettegiver
mulighedforathvismaneksempelvisskalskrivedensammetekstmangegange,kan
manblotskrivevariabelnavnetistedetforatskriveheletekstenigenogigen.Deka
n
eksempelvisbrugessådanher
tekst = "Hello World!".
2
Boolean
EnbooleanerenvariabeltypesomkunkanindeholdeværdienTrueellerFalse.Disseer
megetsmartehvismankunskalbrugejaellernej,daværdienikkekanværeandetend
dissetoienbooleanvariabeltype.
3
Statements
EtstatementerenmådeatautomatisereenprocessiPython.Detkaneksempelvisvære
atdenskalkør
erdensammekodeetantalgange,elleratdenkunmåkørerdennekode
hvisdennevariableer1.Vivilhergennemgårnogleafdestatementsmankanlavei
Python
If
Etifstatementeretstatementhvormanharetparametersomskalværeopfyldt,dettekan
eksempelvisværeata==1,såhvisvoresparametererdette,såvilvoreskodeseudpå
følgendemåde:
if a == 1:
print("a er 1")
el
if a == 2:
print("a er 2")
else:
1
https://docs.python.org/3/library/functions.html#int
2
http://www.learnpython.org/en/Basic_String_Operations
3
https://docs.python.org/3/library/functions.html#bool
5
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
print("a er ikke 1 eller 2")
Dettevilgøreathvisvoresvariabelaer1såprinterden1ellershvisaer2såprinterden
aeraoghvisingenafde2statementspasser,såprinterdenaerikke1eller2.
Nårmanbrugerifstatements,behøvermanikkeathaveenelifellerelse,detervalgfrit.
For-løkker
Forløkkerharmulighedentilatkørerdensammekodexantalgange.Dettekanbrugestil
enmasseforskelligeting,nårmanlaverenforløkkeserdetudpåfølgendemåde:
for
x
in
range
(
0
,
3
):
print
(
x)
Denkodeviharivoresforløkkevilsåblivekørt3gangeogidettetilfældevildenprinte
entekstudsomsigerhvormangegangedenharkørt.
While-løkker
Whileløkkermindermegetomforløkker,mengiverdognogleandremuligheder.Ien
whileløkkevilkoden
dererindenidenkøreruendeligegangeindtildetstatementman
giverdenikkeersandtmere.Dettekunneeksempelvisvære:
a
=
1
While
a
<
100:
print
("
a er lavere
end
100
")
a
=
a
+
1
Operatører
Operatørererligesomoperatørerimatematik,undtagenatprogrammeringssprogsom
Pythonharnogleflereindblandet,sommananvender.Dettekunneeksempelvisværeen
operatørsom!=,
dettebetyderathvisvoresvenstresideafvoresoperatørikkeerdet
sammesomhøjreside,såvildenkørervoreskodeivoresstatement.
Funktioner
Enfunktionenmådeatdelesinkodeopismåblokke.Funktionererblotligesomvariabler,
undtagenatenfunktionkanhavemangelinjerskodeindeisig.Vedatbrugefunktioner
kanmansparerigtigmegetpladsisinkode,hvismanharenprocess
somgentages
mangegange.Mankansendeværdiertilenfunktionsådenikkealtidbaregiverdet
sammeresultat.Enfunktionkaneksempelvissesådanherud:
Sum(a,b):
return
a
+b
Herkanmansåkørerdennefunktionvedatskrive:
print
(
Sum
(
1
,
2)
Vivilsåfåprintettallet3udefterviharkørtdennefunktion.
Klasser
klassererogsåenmådeatdelesinkodeop,ligesomvedfunktioner.Fordelenvedklasser
eratmankanhavefunktionerindenisineklasser,hvilketgivermulighedforenmeget
størreogavanceretprogramendhvisdetvarenfunktion.Klassergiverogsåenmulighed
foratlavesinkodeobjektorienteretsomharendelfordelesomvivilkommeindpåi
næsteafsnit.
6
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Nårmanlaverenklasseskalderaltidværeet__init__afsnit,detteafsniterdetkodesom
vilblivekørthvismanblotskriverklassensnavnudenatvælgeenafdensfunktioner.Et
eksempelpåenklassevillevære:
Class
HelloWorld:
def
__init__
(
self
,
message
=
"Hello World"
):
self
.
message
=
message
def
Write_Message
(
self
):
print
(
self
.
message)
class
=
HelloWorld
()
class
.
Write_message
()
Detteeksempelvilprintevoresbeskedsomer“HelloWorld”nuhvordeterbyggetopien
klasse.Manvilledogikkebrugeenklassepådennemåde,dadenneopgaveermeget
simpel,menmanbrugerklassertilnoglestørrefunktionerenddette.
Objektorienteret
ObjektorienteretkodeiPythonerenspecielmådeatbyggesinkodeoppå,somgiveren
mulighedentilatm
egetlettereogflotterekanbrugedensammekodeogskrivekodenpå
enmådesomermere“logisk”formennesketstankegang.Foratkunnelavesinkode
objektorienteret,skalvibrugeklasserogfunktionertildette,vivilderforlaveeteksempel
somviserhvordanbrugenafobjektorienteretkodekanværetilstorgavnoggiveren
megetlettereforståelseafhvadmangør.Vilaverderforeteksempe
lhvorprogrammets
formåleratværeensbankkonto,såmankansehvormangepengemanhar,trække
pengeudogsættepengeind.
Førstdefinereviklassen:
class
bankkonto
(
object
):
Initerendelafenklassesomaltidskalværeder,deterdenlinjekodesomvilblivekørt
hvismanikkerefereretiletelementiklassen.Detviskriverhererstartbeløbetsom
klassenskalværepånårmanlaver
sinkonto.
def
__init__
(
self
,
startbeloeb
):
self
.
saldo
=
startbeloeb
Derefterlaverviklassensfunktiontilatsættepengeind.Denneklassertagetvoressaldo
somvistartedemedatdefinereogtilsætterdetbeløbsomviharvalgtatderskulle
indbetales.
def
indbetaling
(
self
,
beloeb
):
self
.
saldo
=
self
.
saldo
+
beloeb
Derefterlavetviklassensfunktiontilathævepenge.Dennefungerepræcissomdentilat
sættepengeind,bortsetfraatdeteretminusistedetforetplus.
def
haeve
(
self
,
beloeb
):
self
.
saldo
=
self
.
saldo
+
beloeb
Tilslutlavervifunktionentilatfåvoressaldopåkontoen,detteerbareenreturnpåvores
saldoværdi.
def
saldo
(
self
):
return
self
.
saldo
Foratvikansehvorfordetteerensmartmådeatbyggevoreskodeoppå,laverviså
eksemplermed3personersomskalsættepengeind,hæveogsederessaldo.deharalle
sammenforskelligestartbeløb.
Emil
=
bankkonto
(
400)
7
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Oliver
=
bankkonto
(
30000)
Jakob
=
bankkonto
(
700.50)
Emil
.
haeve
(
100
)
Emilhar300kronertilbage
Jakob
.
indbetaling
(
1000)
Jakobhar1700.50kronernu
Oliver
.
haeve
(
30000)
Oliverharingenpengetilbage
print
(
Emil
.
saldo)
Printer300kroner,dadeterEmilssaldo.
print
(
Jakob
.
saldo)
Printer1700.50kroner,dadeterJakobssaldo.
print
(
Oliver
.
saldo)
Printer0kroner,dadeterOliverssaldo.
Biblioteker
BibliotekernebliverkaldtformoduleriPython.Modulerminderrigtigmegetomklasserog
funktioner,fordideerrentfaktiskerdetsamme.EtModulerblotenfunktionsomman
importerefraenfil,såmankanbrugedenienskode.Grundentilatmanlaverdisse
modulererhvismanharenfunktionsommanaltidbrugerisineprogrammer,såkanman
blotlaveeni
mportpådenoghvismanharbrugforatændrelidtifunktionenkanman
ændredenforallesineprogrammerpåengangistedetforatskulleåbneallesine
programmeropforatændredet.Modulereroftestbrugthvismanvildelesinkodemed
andrefolk,sådekanfåglædeafdenkodemanharlavet.
Qt
Qteretcrossplatformframework,hvilketbetyderatdetkanbrugespåalleenhedermed
lille
elleringenændringikoden.Qteretmegetbrugtframeworkogkanbrugestilatlave
enmasseforskelligetyperapplikationer,såvelsomwebapplikationerogmobil
applikationer.VedbrugafframeworkssomQtermanistandtilatlaveavanceretkode
megetsimplere,daQttagersigafmegetafkodenogblotgørviskalkaldederes
funktioner,ligesomnårmanlaveretobjektorienteretprogram.
Wrappers og PyQt
EnWrapper(ogsåkaldtbibliotekwrapper)eretbiblioteksomtagernogeteksisterende
kodeoggørdetlettereatbrugeellergørsåmankanbrugekodenoverflereforskellige
sprog.ForeksempelvisPyQt,somvibrugerivoresspil.PyQterenwrappertilPythonfra
Qt.DetPyQtgører,atdentageralledefunktionersomalleredefindesiQt,mensomer
skrevettilprogrammeringss
progetC++ogoversætterdemtilPythonkode,såfolksom
programmereiPythonnueristandtilatbrugeQt.
Multi-trådning
Atmultitrådesitprogrambetyderatmankørerflereinstanserpåengang,detteernoget
manoftestikkeharbehovforatgøre,menderkandogværetilfældehvormultitrådning
ernødvendigt.Tidspunkterhvormanharbrugformultitrådningernårmaneksempelvis
haretp
rogramsomskalkørernogetkodeefternogettidogdetoveniskalkørernoget
andetkodeimensprogrammetventer.Etgodteksempelvilleværehvisviharetprogram
somanmoderometsvarfraenhjemmesideogimensdengørdettevilmangerneværei
8
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
standtilatkunnebrugebrugergrænsefladen.Vedatgøresåanmodningentil
hjemmesidenerientrådfrasigselv,giverdetmulighedforatbrugerenkanbruge
brugergrænsefladenimensatdenanmoderhjemmesiden.Hvisdetikkevarmultitrådet,
såvillebrugerenikkekunnetrykkepånogetibrugergrænsefladenindtilprogrammet
havdefåetetsvarfrahjemmesiden.
Design af brugergrænseflade
VoresbrugergrænsefladeerskrevetiQtogdetmesteafdenerlavetiQtDesigner,derfor
vilderikkeværesærligmegetkodeivoresprogramsomerdesignaf
brugergrænsefladen,dadenerlavetiQtDesigner.Davilavedevoresbrugergrænseflade
togvihøjdefordefølgendeting:
Trykfølsommeskærme(F.eks.iPad)
Uendeligantaltingmankankøbe
Mørkerefarver
Sammedesignpåbilleder
Tydeligindikati
onafmængdepengemanhar
MulighedforAchievements,statistikkerosv.
Tydeligindikationafhvormegetdenkosteroghvormegetmantjenerpåden.
EgetWindowslogoogvinduelogo.
Detteblevsåvoresendeligebrugergrænseflade,udfravoreslisteaftingsomvivilletage
højdefor
Mådenvivalgteatimplementerevoreskrav,fikopfyldtdeflesteafkravene,mennogleaf
kraveneblevdogikkeløstpådenoptimalemåde,menmedenløsningsomburdekunne
9
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
dækkevoresbehov.Enafdekravhvorviblevnødttilatofrelidtfunktionalitetvar
angåendeubegrænsettingmankankøbe.Voresprogramharengrænsepåhvormange
tabsvikanlave,mendetteermegethøjt,såviregnerikkemedatdetvilbliveetproblem,
daviikkeforventeratlaveover8tingmankankøbe.
Programmeringssprog
ViharvalgtatkodevoresspiliPython3.4,grundentilatviharvalgtPythonerfordideter
detsprogvierblevetundervistiogvihavdealleredeerfaringmedPythonførviblev
undervistidet.
Pythoneretprogrammeringssprogsomermegetletlæseligtforandrefolkendpersonen
somharskrevetdet.DetteerdetfordiatPythonharenmassereglerforformateringen,for
eksempelbrugerPythonindrykforatindikereatnuskrivermaneksempelvisinde
isit
statement.Denneopbygninggørdetendellettereatlæse,damanhurtigerekansehvad
dererendelafensstatement.
Pythoneretfortolketprogrammeringssprog,dettevilsigeatiPythonskalmanikke
kompileresinkodeførmankankørerdet.Dettegørdetmegetlettereforosattestevores
program,daviikkeskalventepåatprogrammeterkompileretfærdigførvikankommei
gangmed
atteste.
10
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Flowchart
Hervisesetsimplificeretflowchartovervoresprogramsprocess(er)
Iafsnittetimplementeringvilvigåidetaljer.
11
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Implementering
Vivilnugåigennemkoden,ogforklarehvordanprogrammetsskeleterbyggetop,stykke
forstykke.Detereventueltengodidéathavevoresflowchartnårdetteafsnitlæses
igennem,dadeternemmereatforståhvismanharnogetvisueltatbindedetoppå.
Vistartermedatimporteredelibrariessomvibenytterivoreskode.
Threadingbenyttestilatkørevisseprocesseriandrethreads,hovedsageligtforatgøre
detmuligtatkunneinterageremedbrugergrænsefladenimensatvoresPointLoop()
funktionstårogventer.Seteoriafsnitfornærmereforklaringomthreading.
Timebenyttervitilatbedeprogrammetomatvente,dettebenytteskunivor
es
PointLoop()funktionforatfådentilatvente1sekund,føratpointstællesop.
SysbenyttesafPyQTtilf.eks.atvisehovedvinduetgennemwindows.
Randombenyttestilatgenererevorestilfældige“nyheder”somviprintertilvores
nyhedsfelt.
PyQTerdetlibrarysomvibenyttertilvoresbrugergrænseoverflade.
Ctypesbenyttestilkortatopdatereprogrammetsthumbnail(billede)iWind
ows.
Hererklærervivoresvariablersomvibenyttersenereikoden.
PointLoopIntervalereninteger,sombestemmerintervalletsomprogrammetskalvente
pertur,føratPointLoop()funktionenskalkøreigen.
Start_points(integer)erdenmængdeafpointssomspillerenstartermed,dener
nuværendesattil5000fordiatvieritestfasen,mennormalskalspillerenstartemed0.
Interval_Arrayer
enintegersombestemmerintervalletsomGenerateLine()skalventefør
atdenmåkøreigen.
12
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
LVL_1_Arrayerenlistemedforskelligestrings,somerdenyhedsstumpersomprintestil
voresbrugergrænsefladehvert30.sekund.
HerervoresPointLoopfunktion,somkørerienkonstantloopforatgenererepoints
udfrade“ting”somspillerenejer.
Vistartermedatdefinereenfunktion,idettetilfældeudennogleargumenter.
DafunktionenskalkøreietuendeligtloopstartervimedatsættekodenunderwhileTrue:
somvilfåkodentilatblivevedmedatgentagesigselv,sålængeatTrue:erTrue:,hvilket
denjoa
ltidvilvære.
Dadennefunktionskallæggepointstilensinventory,erdetnetopdetsomvistartermed
gøre.
inv.pointshiverfativoresinventorypoints,altsådepointssomvialleredeharoptjent
gennemgenereringogmanuelleklik.
inv.MonsterPoints()erenfunktionsomgårgennemarrayafallemonstreogreturnereralle
deressamledepoints.
Regnestykketgåraltså:Nuværendepoints+Al
lemonsterpoints=Nuværendepoints
Pådenmådefårvialtsåopdateretvoresinv.pointsmedalledegenereredepoints.
Viprinterderefterresultatettilkonsollen(bareforattesteomdetvirker),ogopdaterer
derefterbrugergrænseoverfladenmedhvormangepointsspillerennuhar.
QuestWindowervinduetsnavn,ogCurrentPointserdenQLabelforoven,somviseros
hvormangepointsspiller
enhar.Vikonverterervoresnuopdateredeinv.pointstilenstring,
ogopdatererCurrentPointsmedresultatet.$sættesforantallet,foratviseatdeter
penge.
Vibederherefterprogrammetomatsove,ogpegerpåvariablen(int)PointLoopIntervalfor
hvorlangttidprogrammetskalsove.Somerklæretpålinje14skalfunktionensovei1
sekundt.Idetatdennefunktionstartesienanden
threadendbrugergrænsefladen,ervi
stadigistandtilatinterageremedprogrammetselvomdennethread“sover”.
13
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Hergenererervidetnyhedsfeltsomsesibundenafbrugergrænsefladen
Isammestilsomfunktionenførdefinerervienfunktion,ogfårdentilatkøreuendeligtved
brugafwhileTrue:somaltidvilværesand.
Videfinererenvariabelvednavnrandvar,somtagerettilfældigttal(via
random.randrange)baseretpålængdenafvoresarrayLVL_1_Array.Dettereturnerer
altsåenintegersomer
mellem0oglængdenafvoresarrayistørrelse.
Vibenytterdennevariabeltilatopdaterevoresbrugergrænseflade.NewsFeedernavnet
pådenQLabelsomskalopdateres.Viopdatererdenvedatkaldenavnetpåvoresarray
medetgiventnummer(randvarvariabel),pådenstringsomvigodtvilsætteQLabeltil.
Foreksempelhvisrandvarbliversattil3vilderibrugergrænsefladenståGoddag!fordiat
Goddag!erentrynummer3ivores“LVL_1_Arrayliste.
Tilsidstbedervifunktionenomatsoveietgiventtidsrum,foratdenkørerigen.Dette
tidsrumstammerfravariablen(int)Interval_Arrayogersattil30sekunder.Fordiatdenne
funktionerkaldttilatstarteienandenthread,såsidderrestenafprogrammetikkefast
imensatden“sover”.
Herererklærerviklassenmonster(object):
Viererklærerkortatdennetypekanhave3argumenter.
self.pointshvilketerdenmængdeafpenge/pointssommonsteretgenerererpersekund.
DettebenyttervitilatgenerereiPointLoop()samttrækkepointsfraunderkøbi
MonsterAdd().
self.pricehvilketerdenprissomdetkosteratkøbemonsteret.Dettebenyttervii
MonsterAdd()
self.namenavnetpåmonsteret,somvibenyttertilattællehvormangemonstrederertil
nårviskalgenererepointsgennemMonsterCount()
14
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Inventory(object)classenindeholderallefunktionersomtilladerosatinterageremed
monsteroginventory
Vistartermedatdefineremængdenafpointssomspillerenskalstartermed,denneværdi
ergivenafstart_points(linje15)self.AllMonsterdefineresherefter,detteervoresarray
somindeholderallevoresmonstre,denstartermedatværetomindtilspillerenharkøbt
noget.
MonsterA
dd(self,monster):
MonsterAdderfunktionenderkøresnårenspillerkøberetmonster.
Dercheckesførstomspillerenharnokpointstilatkøbemonsteret,hvisself.pointser
højereendmonster.pricegårvividere,ellerssåsmideserenQMessageBox.warningsom
informererspillerenathanikkeharnokpenge.
Hvisviharnokpointssåappender(tilføjer)videtgivnemonstersomspillerenp
røverat
købe,tilvoresAllMonsterliste.
Dereftertrækkesprisenafmonsteretfravoresinventorypoints.
MonsterCount(self,name):
IdennefunktionbenyttervietforloopsomkørergennemlisteAllMonster,medetgivent
Integervariablencountsættesførsttil0
DerefterløbervigennemMonsterCountogtællerénopic
ountvariablen,forhvergangat
detnavnvikaldtefunktionenmed,bliverfundetiliste.
Derefterreturnerervicount,somermængdeafmonstreafdetgivnenavn.
MonsterPoints(self):
DennefunktionbenytterogsåetforloopforatgågennemlisteAllMonster.
Idettetilfældegårdengennemallemonstersogtilføjerderesmonster.pointstilpoints
variablen,somviderefterreturnerer.
15
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Kortsagt,erdennereturneredeværdisummenafallevoresmonstrespoints.Denneværdi
benyttestilatlæggesovenivoresnuværendeinventorypoints,iPointLoop():funktionen.
Herdefineresdeforskelligemonstre,udfra“points,priceogname”
Inventoryclassenbliverogsåbindedtilinv,sådansåvikankaldedensomf.eks.
inv.points
HerstartesfunktionernePointLoop()ogGenerateLine()ideresegnethreads
somsagttidligere,tilladerdetfunktionerneat“sove”,udenatprogrammetogbrugergrænsefladensidder
fast.
16
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Herstarterbrugergrænsefladekoden,ogdedeleafvoreskodehvor
devisuelleelementeropdateres.
DeførstelinjererPyQTsomindlæses,vierklæreratvoreshovedvinduehedder
QuestWindowogeraftypenQMainWindow.
Viloaderdereftervores“uifil”vednavnproUI.uisomindeholderaltdesignetfraknappertil
helebrugeroverfladen.DereftersættesvinduetstiteltilQuestTyper,ogprog
rammetsikon
iWindows,tilenlilletroldmand.
HerbinderviknappenavatartilfunktionenClickAvatar,somgenerererétenkeltpointtilspillerens
inventory,dennefunktionsessenere.
VisætterdereftervoresNewsFeed(QLabel)tiltekstenasdbaresåatdenikkeerblank
nårprogrammetførststartesop.Dervilindenforetsekundståenafdegenererede
stykkertekst,såasdsesaldrigafspillerendetergenereltbareforat
sehvorlangt
programmetkommer,hvisdernuskulleopståenfejl
Herkaldesfunktionensombinderalle“køb”knappernetilderesrespektivefunktioner.
SetUIerenunderfunktionafQuestWindowklassensombinderdeforskelligemonstretil
dekorrekteknapperpåbrugergrænsefladen.
17
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
SetUImodtageraltsånogleargumenter,somdenbenyttertilatkaldefunktionerindenfor
brugergrænsefladen(PyQT)
Itilfældetafmonster_1vilkodenaltsåvære:
price.clicked.connect(buyFunc)
somblivertil:
self.ui.Price_1.clicked.connect(self.buy_1)
Brugergrænsefladenbliverogsåopdaterettilatsigehvormangeafdetbestemtemonster
mannuejer(vedbrugafMonsterCount(
)funktionen)oghvormangepengemantjenerpå
dennetypeafmonster,afhængendeafhvormangemanhar.
Dettefindesved:
Hvormangepointsgenerererdennetypeafmonsterpersekund?*Hvormangemonstre
ejerjegafdennetype?=pointspersekund
(monster.points*inv.MonsterCount(monster_name))
Dennefunktionsørgerforatspilletlukkesnårmantrykker
påESCknappenpåenstastatur
keyPressEventfunktionenerenPyQTfunktionsomvibenyttertilatopfangeombrugeren
trykkerpåEscapeknappenpåderestastatur.
Såsnartatspillerentrykkerpåenknappåderestastaturkøresdennefunktion,hvis
knappervisersigatværeEscape,sålukkesQuestWindowogexit()sørgerforatPytho
n
ogsålukker.
Dennefunktiontilføjer1pointtilspillerensinventory,nårdeklikkerpåderesavataribrugergrænse
overfladen.
Kortsagttilføjes1pointtilinv.pointshvorefteratCurrentPoints(QLabel)manuelt
opdaterespåsammemådesomiPointLoop()funktionen.(derventesikkepåPointLoop
funktionen)
18
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Dererderespektive“buy”funktionerforhvertmonster
Dissefunktionervirkersommellemled,ogeksistererkunforatblivekaldtafsetUI
funktionerne,forsåatkommunikerevideretilGeneralBuyfunktionenmeddekorrekte
argumenter.
Detteledermedpga.restriktioneriPyQtkoden,somviikkefandtenandenvejudenom.
GeneralBuyfunktionenerdetsidsteledikædenforatkøbeetmonster
ogopdateredegrafiskeelementibrugeroverfladen.
GeneralBuybliverkaldtmed3argumenter,monster(navnet),level(mængdenafmonstre)
ogincome(points)
Førsttilføjesmonsterettilvoresinventorylist,vedinv.MonsterAdd()funktionen
Derefteropdateres“level”(QLabel)somviserhvormangemonstreafdentypesomviha
r
dettefindesvedatkaldeinv.MonsterCount()funktionenmedmonsteretsnavn.
Derefteropdateres“income”(QLabel)ved
Hvormangepointsgenerererdennetypeafmonsterpersekund?*hvormangemonstre
ejerjegafdennetype?=pointspersekund
Tilsidstprintervitilkonsollenhvaddererblevetkøbt,foratværesikrepåatkodenvirker,
hvisnubrugeroverfladenskullefejle.
19
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
TilsidstkørerPyQtsineslutfunktionersomsørgerforatvoresmenudukkeroppå
skærmen,nårprogrammetstartes.
20
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Test af programmet
Daviskulletestevoresprogram,testedeviefteromvihavdefåetudførtdekravvihavde
stillettilvoresprogram.Vistartedemedattesteomdefunktionersomvivirkeligmente
varetkravvirkede,dissetingvar:
Brugergrænseflade
Spilletskerne(købaftingogtjenpengepådemovertidudfrahvormangeman
harkøbt)
Knapmankantrykkepå,forattjeneenlilleantal
penge.
Alledissefunktionerfungereogdetvirkerogsåunderekstremesituationer,daviprøvede
atændrerpåværdiernesåaltgavmangeflerepenge.Dogunderstøttervores
brugergrænsefladeikkealtforstoretal,mendetteernogetvivillekunneløsevedatgøre
fontenmindresdesstørretalletbliver,ellervedatsættedetopløftetix.
Programmetshastighedblevikkepåvirketafvoresstresstesto
verhoved,hvilketergodtat
videatdetikkebliverlangsommereafstoretal.
Ovenidissetingsomvimentevarpåkrævet,valgteviogsåattestehvormangeafde
funktionervigernevillehavemedivoresprogramogsåvarder.Dissefunktionerer:
Multitrådning
Lave8tingmankankøbe
Lavebrugergrænsefladenpænogmereavanceret
Gemoglæsfunktion(save+load)
Mulighedforatsælgeting
Sp
eciellebegivenheder(somingenindkomstførmanklipper20gangepåen
specielting)
Lavikonertiltingenemankankøbe
Udafdissetingkanvikonkludereatdervarendelafdemsomviikkenåede.Vifik
implementeretMultitrådning,daviblevnødttildetteførvoresbrugergrænsefladekunne
virkeoptimalt.
21
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Vifiklavetmulighedenfor8tingmankankøbe,menvifikikkelavetikonerafdemalleog
mankanhellerikkesælgeentingnårmanharkøbtden.Vifikikkelavetnoglespecielle
begivenhederellerengemogindlæsfunktion,menselvespilletfungereogdetburde
væremuligtforatatudvikleviderepådetogfåtilføjetdissefunktioner.
Udfravorestestafspilletkanvikonkludereatder
erendelfunktionersomvimangler,
menatselvespilletermegetstabiltoghovedfunktionenispilletmedatkøbeogtjene
pengevirker.
Konklusion
Voresproblemformuleringerblevetopfyldtogvifiklavetetsuccesfuldtinkrementaltspil.
Spilleteristandtilatkunnehæveensindkomstpr.sekundogmankankøbe8forskellige
ting.
Vifikdogikkeimplementeretalledefunktionersomviger
nevillehavehaft,somvillehave
gjortvoresspilspecieltiforholdtilalledeandreinkrementalespilsomfindesiforvejen.
Foreksempelvillevigernehavehaftspeciellebegivenhederivoresspil,mendettehavde
viikketidtilatudvikle,davivalgteatfokuserepåatfåenstabilplatformsomogså
lykkedes.
22
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder
Litteraturliste
Forfatter:AaronSankin
Udgivet:12/022014
http://www.dailydot.com/gaming/cookieclickerjulienthiennotincrementalgames/
https://docs.python.org/3/library/functions.html#bool

https://docs.python.org/3/library/functions.html#int

http://www.learnpython.org/en/Basic_String_Operations
23
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
Bilag
Vores fulde kode
__author__ = 'rooq'
import threading
import time
import sys
import random
from PyQt5 import uic
from PyQt5.QtWidgets import *
from PyQt5 import QtGui, QtCore
import ctypes
#change the windows task bar icon. (it actually tells windows a new app is running,
refreshes icon from default python
myappid = u'mycompany.myproduct.subproduct.version'
# arbitrary string
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
PointLoopInterval = 1
start_points = 5000 # start on 0, use this to debug
Interval_Array = 30
LVL_1_Array = ["Dette er en nyhed", "Dette er en anden nyhed", "Her er en nyhed",
"Goddag!", "Hejsa!"]
def PointLoop(): # multithreaded loop which calculates / updates invento
ry points and
refreshes UI
while True:
inv.points += inv.MonsterPoints()
print("points: " + str(inv.points)) # print to console for debugging purposes
QuestWindow.ui.CurrentPoints.setText("$ " + str(inv.points))
time.sleep(PointLoopInterval) # multithreading prevents time.sleep from hanging
program
def GenerateLine():
while True:
randvar
= random.randrange(len(LVL_1_Array))
QuestWindow.ui.NewsFeed.setText(LVL_1_Array[randvar])
time.sleep(Interval_Array)
class monster(object): # class defines the monster class
def __init__(self, point, price, name):
self.points = point
self.price = price
self.name = name
class Inventory(object):
def __init__(self):
self.
points = start_points
self.AllMonster = []
def MonsterAdd(self, monster):
if self.points >= monster.price: # if enough points, purchase monster
24
Programmeringseksamensprojekt 12. maj2015
OliverNybroeogEmilRysgaard3.Z
Vejleder:JacobDebel
self.AllMonster.append(monster)
self.points = self.points - monster.price
elif self.points <= monster.price:
QMessageBox.warning(QuestWindow, "Oops!", "Insufficient funds!") # throw
warning if lacking funds
def MonsterCount(self, name): # function counts monsters from a given name, returns
integer
count = 0
for m in self.All
Monster:
if m.name == name:
count += 1
return count
def MonsterPoints(self): # used by PointLoop function to generate inventory points
points = 0
for m in self.AllMonster:
points += m.points
return points
inv = Inventory()
monster_1 = monster(2, 5, "1monkey")
monster_2 = monster(5, 5, "2dog")
monster_3 = monster(5, 5,
"3octopus")
monster_4 = monster(5, 5, "4donkey")
monster_5 = monster(5, 5, "5UNNAMED")
monster_6 = monster(5, 5, "6UNNAMED")
monster_7 = monster(5, 5, "7UNNAMED")
monster_8 = monster(50, 10, "8dennis")
AllMonsters = []
AllMonsters.append(monster_1)
AllMonsters.append(monster_2)
AllMonsters.append(monster_3)
AllMonsters.append(
monster_4)
AllMonsters.append(monster_5)
AllMonsters.append(monster_6)
AllMonsters.append(monster_7)
AllMonsters.append(monster_8)
PointLoopTimer = threading.Timer(PointLoopInterval, PointLoop)
PointLoopTimer.start()
GenerateLineTimer = threading.Timer(1, GenerateLine)
GenerateLineTimer.start()
class QuestWindow(QMainWindow):
def __init__(self,
parent=None):
super(QuestWindow, self).__init__(parent)
self.ui = uic.loadUi("proUI.ui", self) # loads the UI, buttons and monsters should
be attached after this line
25
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
#Sets the window name
self.ui.setWindowTitle("QuestTyper")
#Changes the window Icon.
self.setWindowIcon(QtGui.QIcon('icon175x175.jpeg'))
# avatar click
self.ui.avatar.clicked.connect(self.ClickAvatar) # points to function
self.ui.NewsFeed.setText("asd")
# Functions to call buy functions
self.SetUI(monster_1, self.buy_1, self.ui
.Price_1, self.ui.LVL_1, self.ui.Income_1)
self.SetUI(monster_2, self.buy_2, self.ui.Price_2, self.ui.LVL_2, self.ui.Income_2)
self.SetUI(monster_3, self.buy_3, self.ui.Price_03, self.ui.LVL_03,
self.ui.Income_03)
self.SetUI(monster_4, self.buy_4, self.ui.Price_4, self.ui.LVL_4, self.ui.In
come_4)
self.SetUI(monster_5, self.buy_5, self.ui.Price_5, self.ui.LVL_5, self.ui.Income_5)
self.SetUI(monster_6, self.buy_6, self.ui.Price_6, self.ui.LVL_6, self.ui.Income_6)
self.SetUI(monster_7, self.buy_7, self.ui.Price_7, self.ui.LVL_7, self.ui.Income_7)
self.SetUI(monster_8, self.buy_8
, self.ui.Price_8, self.ui.LVL_8, self.ui.Income_8)
def SetUI(self, monster, buyFunc, price, level, income): # PyQT function
price.clicked.connect(buyFunc)
price.setText("$ " + str(monster.price))
level.setText(str(inv.MonsterCount(monster.name)))
income.setText("$ " + str(monster.points*inv.MonsterCount(mo
nster.name)) + "/sec")
def keyPressEvent(self, e): # PyQT function
if e.key() == QtCore.Qt.Key_Escape: # if escape is pressed
self.close() # close QuestWindow
exit()
def ClickAvatar(self): # method used for manually generating points without the usage
of monsters
inv.points += 1
self.ui.CurrentPoints.setText("$ " + str
(inv.points)) # updates the UI manually,
no need to wait for PointLoop
# buy functions pointing to general purchase function
def buy_1(self):
self.GeneralBuy(monster_1, self.ui.LVL_1, self.ui.Income_1)
def buy_2(self):
self.GeneralBuy(monster_2, self.ui.LVL_2, self.ui.Income_2)
def buy_3(self):
self.GeneralBuy(monster_3, s
elf.ui.LVL_03, self.ui.Income_03)
def buy_4(self):
self.GeneralBuy(monster_4, self.ui.LVL_4, self.ui.Income_4)
26
12. maj2015
Programmeringseksamensprojekt
OliverNybroeogEmilRysgaard3.Z
Vejleder:
def buy_5(self):
self.GeneralBuy(monster_5, self.ui.LVL_5, self.ui.Income_5)
def buy_6(self):
self.GeneralBuy(monster_6, self.ui.LVL_6, self.ui.Income_6)
def buy_7(self):
self.GeneralBuy(monster_7, self.ui.LVL_7, self.ui.Income_7)
def buy_8(self):
self.GeneralBuy(monster_8, self.ui.LVL_8, self.ui
.Income_8)
def GeneralBuy(self, monster, level, income):
inv.MonsterAdd(monster) # monsters are added to inventory array
level.setText(str(inv.MonsterCount(monster.name))) # UI is updated displaying
amount of monsters
income.setText("$ " + str(monster.points*inv.MonsterCount(monster.name)) + "/sec")
# UI updated, points per sec
print("bought " + monster.name) # prints purchase to console for debug purposes
app = QApplication(sys.argv)
QuestWindow = QuestWindow()
QuestWindow.show()
app.exec_()
27