Adds some game logic

This commit is contained in:
Nemo 2018-03-04 03:41:11 +05:30
parent 2ddfc7cf25
commit dcf325e73e
4 changed files with 164 additions and 4 deletions

1
gothok/.gitignore vendored
View File

@ -1,7 +1,6 @@
build/
python/
*.cpp
*.py
*.cpp
*.h
*.pyx

5
gothok/game.capnp Normal file
View File

@ -0,0 +1,5 @@
@0x98bd43b3ed130136;
interface Game {
}

157
gothok/game.py Normal file
View File

@ -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

View File

@ -26,12 +26,11 @@ cardlist = state.init('cardlist', 36)
for index, card in enumerate(cards):
location = game.Location.new_message()
location.board.x = index / 6
location.board.x = index % 6
location.board.y = index % 6
card.location = location
cardlist[index] = card
# print(state)
# Now we have an initial state of the game, write it down
f = open('state.bin', 'w+b')
state.write_packed(f)
f.close()