29. november 2001 - 20:59Der er
10 kommentarer og 2 løsninger
algoritme til at tjekke om der er tre på stribe i et spil kryds og bolle!!
Jeg har lavet et spil kryds og bolle, hvor jeg tjekker om der er tre på stribe, ved at løbe igennem 8 if sætninger, hvor hver if sætning tjekker en mulig forekomst af tre på stribe.
Er der nogen der kan komme op med en bedre løsning i form af en mere optimeret algoritme.
Tja, nu ved jeg jo ikke hvordan du repræsenterer din spilleplade, men forestil di et 2-dimensionelt array: int board[3][3];
og du bruger 1 og 2 til at definere de 2 spilleres brikker.
så kan du fx gøre således: int IsWinner() { static int nPattern[8][3] = { // der er 8 løsninger 0,1,2, 3,4,5, 6,7,8, 0,3,6, 1,4,7, 2,5,8, 0,4,8, 2,4,6 };
Okay, funktionen erklærer et static array hvilket vil sige at det allerede findes når programmet starter og IKKE som det måske ser ud, at arrayet oprettes hver gang funktionen kaldes. Spillepladen kan du forestille dig sådan:
0 1 2 3 4 5 6 7 8
De 8 linier du ser i arrayet er mulighederne for 3 på stribe, fx i første række angiver 0, 1 og 2 de øverste 3 felter på spillepladen.
der der så sker i for-loopet er, at arrayet (det med størrelsen 8*3) løbes igennem og der for hver mulighed tjekkes om alle felterne i den kombination er udfyldt med samme \"brik\" (altså 1 eller 2).
Uden at kigge på felterne er der følgende muligheder for 3 på en stribe:
3 Vandret 3 Lodret 2 Diagonalt
Vandrette finder man ved at starte med 0, 3, 6 og checke de 3 næste \"celler\". Lodrette finder man ved at starte med 0, 1, 2 og checke den 3, 6, 4, 7 osv. \"celle\". Diagonale analogt dertil ved at checke 0,4, 8 og 2, 4, 8.
int board[9];
int isWinner() { int i;
// Check vandret for (i = 0; i <=2*s; i += s) { if (board[i] != 0 && board[i] == board[i+1] && board[i] == board[i+2]) return board[i]; };
// Check lodret for (i = 0; i <=2; i++) { if (board[i] != 0 && board[i] == board[i+3] && board[i] == board[i+6]) return board[i]; };
// Check diagonalt s = 8; for (i = 0; i <=2; i += 2) { s /= 2; if (board[i] != 0 && board[i] == board[i+s] && board[i] == board[i+2*s]) return board[i]; }; return 0; }
Og så er det jeg selv synes at jpk\'s måde egentlig er meget nemmere, pænere og lettere at gennemskue. (Selvom board skal være defineret som jeg har gjort, og der mangler en slut \']\' på if\'en med board.)
-> soepro: Du har ret, jeg var lidt for hurtig! (eller skødesløs) Spillepladen skal erklæres som: int board[9]; Men altså stadig \"forestilles\" som: 0 1 2 3 4 5 6 7 8
Og ret igen, der mangler en \']\' på samtlige if-sætninger, så for-løkken kommer til at se sådan ud:
Det var godt set! Denne metode er nok pænere, så længe det drejer sig om en så lille spilleplade. Jeg har dog brugt nøjagtig samme metode som dig til et 4-på-stribe spil engang. Der er jo mange flere muligheder og det er lidt sygt at skulle liste alle sammen...
jpk - Du lyder som om du er lidt inde i brædtspil på computere, så du kan måske hjælpe mig. Jeg kan evt. oprette et spørgsmål, så du også kan få point for det.
Jeg har engang lavet en algoritme til en computermodstander i 4 på stribe. Jeg kunne godt tænke mig at lave en tilsvarende til spillet \"mølle\", men ved ikke helt, hvordan jeg skal gribe den an.
Mølle består jo faktisk af to spil, først lægger man brikker på brættet, dernæst begynder man at flytte på dem.
Er det noget du kender til, så sig til og jeg opretter et spørgsmål.
->alvion: Jeg har aldrig lavet spillet \"Mølle\", men jeg er da klar til at prøve... Det er godt nok lidt tid siden jeg har spillet spillet, så hvis du kort kan fortælle hvad reglerne er? Hvis vi kommer frem til noget brugbart, kan du jo altid oprette et spørgsmål...
For de fleste brætspil gælder det jo at man kan tildele point til de forskellige, mulige træk på et givet tidspunkt. For f.eks. kryds og bolle, er det bedste selvfølgelig at få tre på stribe, men herefter er det bedste at lave \"fælder\" dvs. træk som gør at du kan få tre på stribe næste gang, uanset hvad modstanderen gør:
0 1 2 1 2 0 3 4 5 0 2 0 6 7 8 0 1 0
Da \'1\' ikke kan få tre på stribe, er det bedste træk her 6, fordi \'1\' så vil få 3 på stribe næste gang (enten via 3 eller via 8.)
Sværhedsgrad kan du f.eks. lave ved at lægge en randomize omkring det \"rigtige\" træk, dvs. en vis sandsynlighed for at maskinen laver det rigtige(rigtigste) træk. Hvis randomize (0-100) tallet f.eks. er større end 50 vælges det rigtige træk, ellers vælges et tilfældigt træk. Hvis der er flere rigtige, eller både et helt rigtigt (3 på stribe) eller et næsten rigtigt træk (3 på stribe næste gang) kan du også vælge mellem de to træk og det tilfældige træk.
I skak-spil giver man både brikkerne og trækkene point (bedre at slå en dronning eller en løber, end en bonde - og omvendt bedre at miste en bonde end en dronning, bedst selvfølgelig at slå kongen, næstbedst at sætte ham skatmat osv.) For det fleste brætspil vil man relativt enkelt kunne opstille en \"point-tavle\" over hvilke pladser på spillet der er bedre end andre - ligesom de fleste vel vil mene at plads 5 i kryds og bolle er den bedste at starte på. (Så kan man ikke tabe - men heller ikke vinde, hvis modstanderen ikke laver fejl.)
--> jpk Tusind tak for dit fine svar, da du var den hurtigste til at svare får du 25 point.
--> Det bliver ikke dit svar jeg brugte, men alligevel synes jeg du har fået skrevet en masse godt i dette indlæg, som jeg gerne vil belønne med 5 point.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.