dummy nimm KI

This commit is contained in:
2025-07-08 16:44:28 +02:00
commit 8d4cb47c57

76
nimm.py Normal file
View 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.")