Adds some game logic
This commit is contained in:
parent
2ddfc7cf25
commit
dcf325e73e
|
@ -1,7 +1,6 @@
|
||||||
build/
|
build/
|
||||||
python/
|
python/
|
||||||
*.cpp
|
*.cpp
|
||||||
*.py
|
|
||||||
*.cpp
|
*.cpp
|
||||||
*.h
|
*.h
|
||||||
*.pyx
|
*.pyx
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
@0x98bd43b3ed130136;
|
||||||
|
|
||||||
|
interface Game {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import capnp
|
||||||
|
import state_capnp as game
|
||||||
|
|
||||||
|
|
||||||
|
class State():
|
||||||
|
|
||||||
|
def initBoard(self):
|
||||||
|
self.board = [[None]*6 for _ in range(6)]
|
||||||
|
|
||||||
|
for card in self.state.cardlist:
|
||||||
|
if (card.location.board):
|
||||||
|
x = card.location.board.x
|
||||||
|
y = card.location.board.y
|
||||||
|
self.board[x][y] = card
|
||||||
|
|
||||||
|
def __init__(self, state):
|
||||||
|
self.state = state
|
||||||
|
self.initBoard()
|
||||||
|
pass
|
||||||
|
|
||||||
|
def findVarys(self):
|
||||||
|
for card in self.state.cardlist:
|
||||||
|
if card.house == 'varys':
|
||||||
|
return card.location
|
||||||
|
|
||||||
|
def getPossibleMoves(self):
|
||||||
|
moves = []
|
||||||
|
|
||||||
|
for x in xrange(0, 5):
|
||||||
|
for y in xrange(0, 5):
|
||||||
|
|
||||||
|
if (self.isLegalMoveLocation(x, y)):
|
||||||
|
moves.append((x, y))
|
||||||
|
|
||||||
|
return moves
|
||||||
|
|
||||||
|
def isLegalMoveLocation(self, x, y):
|
||||||
|
varys = self.findVarys()
|
||||||
|
vx = varys.board.x
|
||||||
|
vy = varys.board.y
|
||||||
|
|
||||||
|
# Row/Column must match
|
||||||
|
if (vx == x and vy == y):
|
||||||
|
return False
|
||||||
|
if (vx == x):
|
||||||
|
# Generate all y between y and vy
|
||||||
|
# See if this is the furthest for this card type
|
||||||
|
# newCardType = self.board
|
||||||
|
if (vy > y):
|
||||||
|
l = [(x, i) for i in range(0, vy)]
|
||||||
|
else:
|
||||||
|
l = [(x, i) for i in range(vy+1, 6)]
|
||||||
|
l.reverse()
|
||||||
|
elif (vy == y):
|
||||||
|
# Generate all x between x and vx
|
||||||
|
if (vx > x):
|
||||||
|
l = [(i, y) for i in range(0, vx)]
|
||||||
|
else:
|
||||||
|
l = [(i, y) for i in range(vx+1, 6)]
|
||||||
|
l.reverse()
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
seen = {}
|
||||||
|
|
||||||
|
for (xx, yy) in l:
|
||||||
|
house = self.board[xx][yy].house
|
||||||
|
if str(house) in seen:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# We stop testing as soon as we reach the new location
|
||||||
|
if (x == xx and y == yy):
|
||||||
|
return True
|
||||||
|
seen[str(house)] = True
|
||||||
|
|
||||||
|
|
||||||
|
class GameNode(object):
|
||||||
|
"""docstring for GameNode"""
|
||||||
|
|
||||||
|
def __init__(self, state, parent):
|
||||||
|
super(GameNode, self).__init__()
|
||||||
|
self.state = state
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
self.hits = 0
|
||||||
|
self.misses = 0
|
||||||
|
self.totalTrials = 0
|
||||||
|
|
||||||
|
def backPropagate(self, simulation):
|
||||||
|
if (simulation > 0):
|
||||||
|
self.hits += 1
|
||||||
|
elif (simulation < 0):
|
||||||
|
self.misses += 1
|
||||||
|
self.totalTrials += 1
|
||||||
|
|
||||||
|
if self.parent:
|
||||||
|
self.parent.backPropagate(-simulation)
|
||||||
|
|
||||||
|
def childPotential(self, child):
|
||||||
|
w = child.misses
|
||||||
|
n = child.totalTrials
|
||||||
|
|
||||||
|
# Chosen empirically
|
||||||
|
c = math.sqrt(2)
|
||||||
|
t = self.totalTrials
|
||||||
|
|
||||||
|
return (w / n) + (c * math.sqrt(log(t) / n))
|
||||||
|
|
||||||
|
def runSimulation(self):
|
||||||
|
self.backPropagate(self.simulate())
|
||||||
|
|
||||||
|
def chooseChild(self):
|
||||||
|
# Define children nodes
|
||||||
|
if(not self.children):
|
||||||
|
self.children = self.getChildren(self.state)
|
||||||
|
|
||||||
|
# Run simulation on leaf nodes
|
||||||
|
if(len(self.children) == 0):
|
||||||
|
self.runSimulation()
|
||||||
|
else:
|
||||||
|
unexplored = []
|
||||||
|
|
||||||
|
# Get all unexplored nodes
|
||||||
|
for child in self.children:
|
||||||
|
if (child.totalTrials == 0):
|
||||||
|
unexplored.append(child)
|
||||||
|
|
||||||
|
# Pick a random unexplored node
|
||||||
|
# and run the simulation on it
|
||||||
|
if (len(unexplored) > 0):
|
||||||
|
random.choice(unexplored).runSimulation()
|
||||||
|
else:
|
||||||
|
# Find the best child
|
||||||
|
bestChild = self.children[0]
|
||||||
|
bestPotential = self.childPotential(bestChild)
|
||||||
|
|
||||||
|
for child in self.children:
|
||||||
|
potential = self.childPotential(child)
|
||||||
|
|
||||||
|
if (potential > bestPotential):
|
||||||
|
bestPotential = potential
|
||||||
|
bestChild = child
|
||||||
|
|
||||||
|
bestChild.chooseChild()
|
||||||
|
|
||||||
|
|
||||||
|
f = open('state.bin', 'rb')
|
||||||
|
initial_state = game.State.read_packed(f)
|
||||||
|
|
||||||
|
# print(initial_state)
|
||||||
|
s = State(initial_state)
|
||||||
|
print(s.getPossibleMoves())
|
||||||
|
|
||||||
|
# 3,2
|
|
@ -26,12 +26,11 @@ cardlist = state.init('cardlist', 36)
|
||||||
for index, card in enumerate(cards):
|
for index, card in enumerate(cards):
|
||||||
location = game.Location.new_message()
|
location = game.Location.new_message()
|
||||||
location.board.x = index / 6
|
location.board.x = index / 6
|
||||||
location.board.x = index % 6
|
location.board.y = index % 6
|
||||||
card.location = location
|
card.location = location
|
||||||
cardlist[index] = card
|
cardlist[index] = card
|
||||||
|
|
||||||
# print(state)
|
|
||||||
|
|
||||||
# Now we have an initial state of the game, write it down
|
# Now we have an initial state of the game, write it down
|
||||||
f = open('state.bin', 'w+b')
|
f = open('state.bin', 'w+b')
|
||||||
state.write_packed(f)
|
state.write_packed(f)
|
||||||
|
f.close()
|
||||||
|
|
Loading…
Reference in New Issue