webForumDet fria alternativet

Fyra i rad-AI-demo

C/C++

9 svar · 1 355 visningar · startad av Sang-drax

Medlem sedan juli 2002581 inlägg
Frågan#1

Jag har gjort ett litet program för att testa hur man kan göra en ganska bra AI relativt enkelt till ett brädspel.

Fyra i rad är ett tacksamt spel, eftersom det varje omgång endast finns som mest sju möjliga drag. Detta gör att det går smärtfritt att söka ganska långt efter möjliga drag.

Programmet söker efter drag och väljer det som ser bäst ut i det långa loppet mha en enkel funktion som värderar olika positioner. Jag gjorde det enkelt för mig och tilldelade olika poäng till pjäserna beroende på var de låg på spelplanen. Det fungerar dock mycket bra.

Källkod och exekverbar fil för Windows följer med, men det bör vara ganska lätt att få det att kompilera för andra plattformar. Jag har lagt det som då behöver ändras i en speciell fil.

Är det någon som kan slå datorn på det svåraste?

Medlem sedan juni 20014 421 inlägg
#2

Härligt spel, har spelat fyra i rad en jag gick på frititds, det började med att jag vann över alla som gick på samma fritids, för att sedan fortsätt med att vinna över alla föreståndare. :e

Lyckades knäck han 1/2 gånger spelade....jag ska spela en bäst av tre senare....

Medlem sedan juli 2002581 inlägg
#3

Ahh, en duktig spelare!

Har du någon medveten taktik när du spelar? I så fall kanske jag kan förbättra funktionen som utvärderar spelplanen.

Just nu tilldelar jag bara poäng till varje spelpjäs beroende på var den ligger på 'brädet'.

//│1│2│3│4│3│2│1│
//│2│3│4│5│4│3│2│
//│3│4│5│6│5│4│3│
//│2│3│4│5│4│3│2│
//│1│2│3│4│3│2│1│
//│0│1│2│3│2│1│0│
//└─┴─┴─┴─┴─┴─┴─┘

Fördelen med denna metod är att den är snabb.

Testa gärna att ändra i funktionen och se hur datorn spelar.

EDIT: Om du vinner får du gärna skriva hur du vann, dvs hur du flyttade.

Medlem sedan maj 20002 993 inlägg
#4

Borde man inte kunna vinna genom att placera på samma sätt varenda gång med den metoden?

Medlem sedan aug. 20003 575 inlägg
#5

Jag slog den på det svåraste AI *stolt*

untitled.jpg
Medlem sedan juni 20014 421 inlägg
#6

Hmm, nästa match jag tar och vinner ska jag rapportera, det lovar jag.

Jag har egentligen ingrn klar taktik när jag börjar spela utan låter den utveckal sig under tiden.....

En simpel förklaring (gaska uppenbart men ändå): Ser till att ha så många trådar (ställen som ger dig ett försprång) öppna samtidigt som du försöker sabotera för motståndaren. En taktik som nästa alltid fungera är att försöka göra så att moståndaren _ALDRIG_ får mer än två i rad (i den mån det går).
Se till att bygga i alla riktningar nära varandra, speciellt de diagonala och vägrätta är en bra kombination för att tvinga in motståndarna i ett hörn.

Det är dessutom lättare att spela mot människor då deras sätt att lägga på är lättare att räkna ut.

Medlem sedan juli 2002581 inlägg
#7

Alpha II skrev:

Borde man inte kunna vinna genom att placera på samma sätt varenda gång med den metoden?

Om du menar att om man vinner en gång så kan man vinna igen genom att lägga likadant, så jo.

Algoritmen består ju heller inte bara av ovan nämnda funktion, utan datorn söker igenom att mycket stort antal möjliga spelutvecklingar och väljer den bästa av dem.

EDIT:
En dum grej är att om datorn inser att du kommer vinna någon gång i framtiden (kanske en avlägsen sådan) så kommer den att skita totalt i hur den spelar och bara lägga på den närmast tillgängliga platsen istället för att försöka hindra dig så länge som möjligt.
Det omvända gäller också, när datorn är säker på att vinna kan det ta lång tid innan spelet avgörs, den kan tom strunta i att fullfölja en trea och istället lägga någon annanstans. Till slut vinner han dock.

Detta är dock lätt avhjälpt, det är bara att värdera en vinst närmare i tiden högre än en vinst längre bort i tiden. Jag tror jag ska implementera detta.

Medlem sedan juli 2002581 inlägg
#8

Så, det är bara att ändra de första raderna i AI.cpp till detta:

    //Check if there's a current winner
    char winner = board.checkWin();
    //Calcluate the winning score by taking the depth into
    //account. Winning now is better than winning later, because
    //humans aren't perfect and may not notice that they're sure
    //to win :)
    int winScore = (maxDepth - depth + 1) * maxScore;
    if (winner == 'X')
        return winScore;
    else if (winner == 'O')
        return -winScore;
Medlem sedan maj 20002 993 inlägg
#9

Jag tänkte fippla lite i koden men det gick inte att kompilera koden från början. :( Jag får felmeddelanden om petter-input.h och felmeddelanden överallt där funktionerna används.

Medlem sedan juli 2002581 inlägg
#10

Jaha, det var ju dumt.
Skriv då gärna vad för fel du fick så kanske jag kan hjälpa dig.

petter-input.h kan tas bort om du byter ut get-funktionerna i main() mot cin>> istället.

263 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
137 ms — hämta tråd, inlägg och bilagor (db)
118 ms — ändringar (db)