Juvelbesat algoritme I

Måske kender du spillet Bejeweled eller Jewels fra din iPhone eller Android-telefon. Hvis du gør, så har du sikkert også lagt mærke til, at det er utroligt fængende og meget tidskrævende. Det har jeg i hvert fald lagt mærke til. Så nu har jeg sat mig for at skrive en algoritme, der kan spille det for mig, så jeg ikke selv behøver gøre det.

I denne første artikel beskriver jeg de regler algoritmen skal spille efter.

Der er flere forskellige firmaer, som producer spillet under forskellige navne. Reglerne varierer derfor lidt alt efter producent, platform og version. Jeg har taget udgangspunkt i en simpel variant.

Spillets regler

Spillet består af en spilleplade med 8x8 felter, hvorpå der placeres juveler i 7 forskellige farver. Juvelerne placeres tilfældigt på pladen ved spilstart.

Formålet med spillet er at samle juveler i sæt af 3, 4 eller 5 på række enten lodret eller vandret. Det er af gode grunde ikke muligt at samle sæt på flere end 5 juveler. Juvelerne kan kun flyttes ved at bytte rundt på to juveler enten lodret eller vandret. Når juvelerne samles i sæt, forsvinder de automatisk fra pladen. Jo flere juveler i sættet, jo flere point får man.

Når et juvelsæt forsvinder fra pladen, falder de ovenstående juveler automatisk ned på de tomme pladser og nye juveler "falder ned" i tilfældig orden fra toppen af brættet. Hvis juvelerne danner nye sæt, når de falder ned, forsvinder de nye sæt også automatisk. Pladen fyldes op med juveler, indtil der ikke er flere sæt tilbage på pladen. Jo flere sæt man kan fjerne efter hinanden, jo flere point får man for hvert efterfølgende sæt.

Reglerne for at flytte rundt på pladen er altså simple:

  • En juvel kan kun flyttes ved, at den bytter plads med en anden juvel.
  • Juveler kan kun bytte plads, hvis de er placeret i felter umiddelbart ved siden af, over eller under hinanden.
  • Juveler kan kun bytte plads, hvis der ved ombytningen skabes mindst ét sæt.

Reglerne for point er lidt mere kringlede:

  • Når juveler samles i sæt af 3, 4 eller 5 giver det point
  • Jo flere juveler i sættet, jo flere point giver det
  • Når flere sæt samles i en serie, giver det en bonus
  • Jo flere sæt i serien, jo flere point giver hvert sæt

Det er ikke vigtigt for algoritmen, men for eksemplets skyld har jeg givet juvelerne farver og fastsat nogle pointtal.

  • Juveler kan være røde, grønne, blå, violette, gule, orange eller hvide.
  • Et sæt på 3 juveler giver 100 point.
  • Et sæt på 4 juveler giver 200 point.
  • Et sæt på 5 juveler giver 300 point.
  • Hvert ekstra sæt i en serie giver 300 point mere end det forrige.

Med disse simple regler på plads kan jeg tage fat på næste opgave; at skrive en algoritme.

Udgivet i Blandet | Tagget , , , , | En kommentar

Første kata på plads

Efter dagens karatetræning lykkedes det mig endelig at gennemføre en hel kata uden fejl. Det var ikke perfekt, men herfra er det blot finpudsning af detaljer, før jeg er klar til graduering.

Den første kata vi har lært hedder Gekisai Dai Ichi. De sidste to ord dai ichi betyder ganske enkelt nr. 1, mens gekisai i danske karateklubber oversættes til enten smadre og ødelægge eller angrib og ødelæg. De ordbøger jeg har fundet på nettet oversætter dog gekisai til pulverisere, og det lyder meget sejere. Så altså har jeg nu lært min første kata: Pulvisere nr. 1.

På Youtube kan man se den i rigtig mange udgaver, men jeg har fundet den udført af Morio Higaonna, grundlægger af det internationale karateforbund IOGKF og indehaver af 10. dan - den højeste titel man kan opnå i Goju-ryu karate.

Hvis bare den sidder lige i skabet, som når Morio viser den, så skal jeg nok graduere til jul.

Udgivet i Blandet | Tagget | Skriv en kommentar

Beregning af fremdrift med datoer i Excel

Forleden blev jeg spurgt, om jeg kunne skrive en formel i Excel til beregning af hvor mange procent en dato ligger inde i et kvartal. Det viste sig at volde mig lidt større problemer, end jeg lige havde regnet med, for der er ikke nogen enkel metode til at regne med kvartaler. Her er den løsning, jeg kom frem til.

Både regnearket og opgaven er ellers simple. I celle B1 står der en dato, fx =TODAY(). Baseret på B1 alene skal formlen returnere procentsatsen. For overblikkets skyld har jeg  delt beregningen op i flere dele:

Trin for trin er beregningen ret overskuelig. Men når formlerne sættes sammen i en enkelt celle, bliver den vanskelig at arbejde med, fordi hver formel gentages flere gange.

Når formlerne sættes sammen, så der kun refereres til datoen i B1, ser den sådan ud:

=(B1-DATE(YEAR(B1);(INT((MONTH(B1)-1)/3))*3+1;1)+1)/(EOMONTH(DATE(YEAR(B1);(INT((MONTH(B1)-1)/3))*3+1;1);2)-DATE(YEAR(B1);(INT((MONTH(B1)-1)/3))*3+1;1)+1)

Jeg har med vilje valgt at beregne kvartalet, så 1. kvartal bliver 0 og 4. kvartal bliver 3. Det skyldes, at jeg i den sammensatte formel bruger tallet til at finde den første måned i kvartalet ved at gange med 3 og lægge 1 til. Læg i øvrigt mærke til at jeg lægger +1 til ved beregning af kvartalet i øverste eksempel, men at der trækkes -1 fra ved beregning af startdatoens måned. Disse to går ud mod hinanden, og er kun medtaget i delformlerne af hensyn til forklaringen.

Hvis man kun er interesseret i at finde kvartalet, så kan man i stedet bruge formlen =ROUNDUP(MONTH(B1)/3;0). Det er lidt smag og behag.

Der er ikke umiddelbart nogen vej uden om at skrive formlen i B2 tre gange, da kvartalet er udgangspunkt for alle beregningerne. Men hvis man alligevel har brug for kvartalet i en anden celle, fx B2, så bliver formlen lidt mere overskuelig:

=(B1-DATE(YEAR(B1);(B2-1)*3+1;1)+1)/(EOMONTH(DATE(YEAR(B1);(B2-1)*3+1;1);2)-DATE(YEAR(B1);(B2-1)*3+1;1)+1)

Hvis man har brug for at beregne fremdriften på måneds- og årsbasis, så er det heldigvis meget enklere:

=DAY(B1)/DAY(EOMONTH(B1;0))

=(B1-DATE(YEAR(B1);1;1)+1)/(DATE(YEAR(B1);12;31)-DATE(YEAR(B1);1;1)+1)

Slutnote: Da jeg skrev formlen første gang forleden, begik jeg en klassisk fejl. Når man vil beregne antal dage mellem to datoer, skal man huske at lægge +1 til, når man trækker datoerne fra hinanden. Det er selvfølgelig rettet i ovenstående eksempel.

Udgivet i Excel | En kommentar