Skip to content

Commit

Permalink
Truncated lines + contributor notes
Browse files Browse the repository at this point in the history
  • Loading branch information
mrfesol committed Apr 14, 2015
1 parent ccc6f5d commit 9c46f3b
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 34 deletions.
1 change: 1 addition & 0 deletions easyAI/AI/DUAL.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#contributed by mrfesol (Tomasz Wesolowski)

from easyAI.AI.MTdriver import mtd

Expand Down
34 changes: 18 additions & 16 deletions easyAI/AI/MTdriver.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#contributed by mrfesol (Tomasz Wesolowski)

inf = 1000000
eps = 0.001

Expand Down Expand Up @@ -27,15 +29,15 @@ def mt(game, gamma, depth, origDepth, scoring, tt=None):
game.ai_move = lookup['move']
return upperbound

bestValue = -inf
best_value = -inf

if (depth == 0) or game.is_over():
score = game.scoring()

if score != 0:
score = (score - 0.99*depth*abs(score)/score)

lowerbound = upperbound = bestValue = score
lowerbound = upperbound = best_value = score
else:
ngame = game
unmake_move = hasattr(game, 'unmake_move')
Expand All @@ -46,7 +48,7 @@ def mt(game, gamma, depth, origDepth, scoring, tt=None):
game.ai_move = best_move

for move in possible_moves:
if bestValue >= gamma: break
if best_value >= gamma: break

if not unmake_move:
ngame = game.copy()
Expand All @@ -55,20 +57,20 @@ def mt(game, gamma, depth, origDepth, scoring, tt=None):
ngame.switch_player()

move_value = -mt(ngame, -gamma, depth-1, origDepth, scoring, tt)
if bestValue < move_value:
bestValue = move_value
if best_value < move_value:
best_value = move_value
best_move = move

if unmake_move:
ngame.switch_player()
ngame.unmake_move(move)

if bestValue < gamma:
upperbound = bestValue
if best_value < gamma:
upperbound = best_value
else:
if depth == origDepth:
game.ai_move = best_move
lowerbound = bestValue
lowerbound = best_value

if tt != None:

Expand All @@ -79,7 +81,7 @@ def mt(game, gamma, depth, origDepth, scoring, tt=None):
depth = depth,
move = best_move)

return bestValue
return best_value


def mtd(game, first, next, depth, scoring, tt = None):
Expand All @@ -90,15 +92,15 @@ def mtd(game, first, next, depth, scoring, tt = None):
For more details read following paper:
http://arxiv.org/ftp/arxiv/papers/1404/1404.1515.pdf
"""
bound, bestValue = first, first
bound, best_value = first, first
lowerbound, upperbound = -inf, inf
while True:
bound = next(lowerbound, upperbound, bestValue)
bestValue = mt(game, bound - eps, depth, depth, scoring, tt)
if bestValue < bound:
upperbound = bestValue
bound = next(lowerbound, upperbound, best_value)
best_value = mt(game, bound - eps, depth, depth, scoring, tt)
if best_value < bound:
upperbound = best_value
else:
lowerbound = bestValue
lowerbound = best_value
if lowerbound == upperbound:
break
return bestValue
return best_value
1 change: 1 addition & 0 deletions easyAI/AI/SSS.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#contributed by mrfesol (Tomasz Wesolowski)

from easyAI.AI.MTdriver import mtd

Expand Down
37 changes: 19 additions & 18 deletions easyAI/games/Chopsticks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#contributed by mrfesol (Tomasz Wesolowski)

from easyAI import TwoPlayersGame
from easyAI.Player import Human_Player
from copy import deepcopy
Expand All @@ -22,25 +24,32 @@ class Chopsticks( TwoPlayersGame ):

def __init__(self, players, numhands = 2):
self.players = players
self.numplayers = len(self.players)
self.numhands = numhands
self.hands = [[1 for hand in range(self.numhands)] for player in range(len(self.players))]
self.nplayer = 1 # player 1 starts.

hand = [1 for hand in range(self.numhands)]
self.hands = [hand[:] for player in range(self.numplayers)]

def possible_moves(self):
moves = []
#splits
for h1 in range(self.numhands):
for h2 in range(self.numhands):
if h1 == h2: continue
for i in range(1, 1+min(self.hands[self.nplayer-1][h1], 5-self.hands[self.nplayer-1][h2])):
hand1 = self.hands[self.nplayer-1][h1]
hand2 = self.hands[self.nplayer-1][h2]
for i in range(1, 1+min(hand1, 5-hand2)):
move = ('split', h1, h2, i)
if self.hands[self.nplayer-1][h2] + i != self.hands[self.nplayer-1][h1] and self.back_to_startstate(move) == False:
if hand1 != hand2 + i and self.back_to_startstate(move) == False:
moves.append(move)

#taps
for i in range(self.numhands):
for j in range(self.numhands):
if self.hands[self.nplayer-1][i] != 0 and self.hands[self.nopponent-1][j] != 0:
hand_player = self.hands[self.nplayer-1][i]
hand_opp = self.hands[self.nopponent-1][j]
if hand_player != 0 and hand_opp != 0:
moves.append(('tap', i, j, self.hands[self.nplayer-1][i]))
return moves

Expand All @@ -52,7 +61,7 @@ def make_move(self, move):
else:
self.hands[self.nopponent-1][two] += value

for player in range(len(self.players)):
for player in range(self.numplayers):
for hand in range(self.numhands):
if self.hands[player][hand] >= 5:
self.hands[player][hand] = 0
Expand All @@ -67,7 +76,7 @@ def is_over(self):
return self.lose() or self.win()

def show(self):
for i in range(len(self.players)):
for i in range(self.numplayers):
print("Player %d: " %(i+1)),
for j in range(self.numhands):
if self.hands[i][j] > 0:
Expand All @@ -85,7 +94,7 @@ def scoring(self):
if self.win():
return 100
alive = [0] * 2
for player in range(len(self.players)):
for player in range(self.numplayers):
for hand in range(len(self.hands[player])):
alive[player] += (self.hands[player][hand] > 0)
return alive[self.nplayer-1] - alive[self.nopponent-1]
Expand All @@ -94,7 +103,7 @@ def ttentry(self):
"""
Returns game entry
"""
entry = [self.hands[i][j] for i in range(len(self.players)) for j in range(self.numhands)]
entry = [self.hands[i][j] for i in range(self.numplayers) for j in range(self.numhands)]
entry = entry + [self.nplayer]
return tuple(entry)

Expand All @@ -104,18 +113,10 @@ def back_to_startstate(self, move):
"""
nextstate = self.copy()
nextstate.make_move(move)
hands_min = min([min(nextstate.hands[i]) for i in range(len(self.players))])
hands_max = max([max(nextstate.hands[i]) for i in range(len(self.players))])
hands_min = min([min(nextstate.hands[i]) for i in range(self.numplayers)])
hands_max = max([max(nextstate.hands[i]) for i in range(self.numplayers)])
return hands_min == 1 and hands_max == 1

def flat_list(x, l):
"""
Helper - converts nested lists to flat one (required to store game state)
"""
if type(x) != list: l += [x]
else:
for i in x: flat_list(i, l)

if __name__ == "__main__":
from easyAI import Negamax, AI_Player, DictTT, SSS, DUAL
ai_algo_neg = Negamax(4)
Expand Down

0 comments on commit 9c46f3b

Please sign in to comment.