dummy nimm KI
This commit is contained in:
76
nimm.py
Normal file
76
nimm.py
Normal file
@ -0,0 +1,76 @@
|
||||
import random
|
||||
from dataclasses import dataclass
|
||||
|
||||
@dataclass
|
||||
class Move:
|
||||
state: int
|
||||
move: int
|
||||
|
||||
def optimal_move():
|
||||
global state
|
||||
for n in [1, 2, 3]:
|
||||
if (state - n) % 4 == 1:
|
||||
return n
|
||||
return random.randint(1, 3) # Wenn keine perfekte Wahl, dann irgendein Zug
|
||||
|
||||
def ki_move():
|
||||
global state
|
||||
antiMoves = lostMoves.get(state)
|
||||
if antiMoves == None:
|
||||
return random.randint(1, 3)
|
||||
availableMoves = [True, True, True]
|
||||
for badMove in antiMoves:
|
||||
availableMoves[badMove - 1] = False
|
||||
for i, good in enumerate(availableMoves):
|
||||
if good:
|
||||
return i + 1
|
||||
return random.randint(1, 3)
|
||||
|
||||
def makeMove(move): # gibt True zurück, wenn der Spieler verloren hat
|
||||
global state
|
||||
state -= move
|
||||
|
||||
# state kann auch kleiner 0 sein, da der Einfachheit halber am Ende auch Züge gemacht werden,
|
||||
# die mehr alle Hölzchen wegnehmen. Dies wird dann so betrachtet, wie als wären 0 Hölzchen da.
|
||||
return state <= 0
|
||||
|
||||
def addLostMove(state, move):
|
||||
moves = lostMoves.get(state)
|
||||
if moves == None:
|
||||
moves = []
|
||||
moves.append(move)
|
||||
|
||||
def game(train):
|
||||
global state
|
||||
state = 12
|
||||
lastMove = None
|
||||
while True:
|
||||
# KI beginnt, sonst kann sie nicht gewinnen
|
||||
move = ki_move()
|
||||
lost = makeMove(move)
|
||||
if lost:
|
||||
if train:
|
||||
addLostMove(state + move, move)
|
||||
addLostMove(lastMove.state, lastMove.move)
|
||||
return 0 # optimale Strategie hat gewonnen
|
||||
lastMove = Move(state + move, move)
|
||||
|
||||
move = optimal_move()
|
||||
lost = makeMove(move)
|
||||
if lost:
|
||||
return 1 # KI hat gewonnen
|
||||
|
||||
state = 12
|
||||
lostMoves = {}
|
||||
|
||||
# train
|
||||
for _ in range(1000):
|
||||
game(True)
|
||||
|
||||
# eval
|
||||
numberEvalGames = 100000
|
||||
wonGames = 0
|
||||
for _ in range(numberEvalGames):
|
||||
wonGames += game(False)
|
||||
|
||||
print(f"Die KI hat {wonGames / numberEvalGames * 100}% der Spiele gewonnen.")
|
||||
Reference in New Issue
Block a user