Skip to content

Instantly share code, notes, and snippets.

@corvuscrypto
Last active February 16, 2016 17:49
Show Gist options
  • Save corvuscrypto/1183425a6ea236d3ba07 to your computer and use it in GitHub Desktop.
Save corvuscrypto/1183425a6ea236d3ba07 to your computer and use it in GitHub Desktop.
Peg-game solver based on a greedy probabilistic algorithm that came straight out of your worst efficiency nightmares
import random
import copy
# 0
# 1 2
# 3 4 5
# 6 7 8 9
# 10 11 12 13 14
#
#
START = 0
network = None
class Network():
def __init__(self):
self.nodes = {}
self.peg_nodes = [i for i in range(15) if i != START]
self.move_list = []
def reset(self):
for i in range(15):
if i == START:
self.nodes[i].has_peg = False
continue
self.nodes[i].has_peg = True
self.move_list = []
self.peg_nodes = [i for i in range(15) if i != START]
def start(self):
while True:
if not self.do_move():
if len(self.peg_nodes) == 1:
return self.move_list
self.reset()
return False
def add_node(self, node):
self.nodes[node.pos] = node
def do_move(self):
possible = copy.deepcopy(self.peg_nodes)
move_success = False
while not move_success:
if len(possible)>1:
index = random.randrange(len(possible))
else:
index = 0
node = self.nodes[possible[index]]
new_peg_pos, removed_peg = node.try_move()
if new_peg_pos > -1:
#remove the previous location
self.move_peg(node.pos, new_peg_pos)
#remove the jumped peg
self.remove_peg(removed_peg)
#set move_success true
move_success = True
self.move_list.append((node.pos, new_peg_pos))
else:
possible.remove(node.pos)
if len(possible) == 0:
return False
return True
def remove_peg(self, peg_pos):
self.nodes[peg_pos].has_peg = False
self.peg_nodes.remove(peg_pos)
def move_peg(self, old_pos, new_pos):
self.nodes[old_pos].has_peg = False
self.nodes[new_pos].has_peg = True
self.peg_nodes.remove(old_pos)
self.peg_nodes.append(new_pos)
def get_node(self, pos):
return self.nodes[pos]
class Hole():
def __init__(self, pos):
self.pos = pos
if pos == 0:
self.moves = [(1,3),(2,5)]
elif pos == 1:
self.moves = [(3,6),(4,8)]
elif pos == 2:
self.moves = [(4,7),(5,9)]
elif pos == 3:
self.moves = [(1,0),(4,5),(7,12),(6,10)]
elif pos == 4:
self.moves = [(7,11),(8,13)]
elif pos == 5:
self.moves = [(2,0),(4,3),(8,12),(9,14)]
elif pos == 6:
self.moves = [(3,1),(7,8)]
elif pos == 7:
self.moves = [(4,2),(8,9)]
elif pos == 8:
self.moves = [(4,1),(7,6)]
elif pos == 9:
self.moves = [(5,2),(8,7)]
elif pos == 10:
self.moves = [(6,3),(11,12)]
elif pos == 11:
self.moves = [(7,4),(12,13)]
elif pos == 12:
self.moves = [(11,10),(7,3),(8,5),(13,14)]
elif pos == 13:
self.moves = [(8,4),(12,11)]
elif pos == 14:
self.moves = [(13,12),(9,5)]
if pos != START:
self.has_peg = True
else:
self.has_peg = False
def try_move(self):
possible = copy.deepcopy(self.moves)
move_success = False
while len(possible)>0:
if len(possible)>1:
index = random.randrange(len(possible))
else:
index = 0
move_set = possible[index]
## if valid move
is_valid = network.get_node(move_set[0]).has_peg and (not network.get_node(move_set[1]).has_peg)
if is_valid:
return move_set[1], move_set[0]
possible.remove(move_set)
if len(possible)==0:
return -1,None
if __name__ == '__main__':
network = Network()
for i in range(15):
node = Hole(i)
network.add_node(node)
success = False
while not success:
success = network.start()
print success
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment