UserPreferences

KonanePlayerProgram


  1 
  2 
  3 
  4 
  5 
  6 
  7 
  8 
  9 
 10 
 11 
 12 
 13 
 14 
 15 
 16 
 17 
 18 
 19 
 20 
 21 
 22 
 23 
 24 
 25 
 26 
 27 
 28 
 29 
 30 
 31 
 32 
 33 
 34 
 35 
 36 
 37 
 38 
 39 
 40 
 41 
 42 
 43 
 44 
 45 
 46 
 47 
 48 
 49 
 50 
 51 
 52 
 53 
 54 
 55 
 56 
 57 
 58 
 59 
 60 
 61 
 62 
 63 
 64 
 65 
 66 
 67 
 68 
 69 
 70 
 71 
 72 
 73 
 74 
 75 
 76 
 77 
 78 
 79 
 80 
 81 
 82 
 83 
 84 
 85 
 86 
 87 
 88 
 89 
 90 
 91 
 92 
 93 
 94 
 95 
 96 
 97 
 98 
 99 
100 
101 
102 
103 
104 
105 
106 
107 
108 
109 
110 
111 
112 
113 
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 
137 
138 
139 

"""
This module contains a class of a random Konane Player.
The brain KonanePlayer program plays a random game of Konane.
"""

from pyrobot.brain import Brain
import time, random

def otherPiece(piece):
    """ What is the opponent's shape? """
    if piece == 'O': return 'X'
    else: return 'O'

def getEmpties(board):
    """ Returns all of the empty positions on board. """
    retval = []
    for i in range(8):
        for j in range(8):
            if board[i][j] == '':
                retval.append( (i+1, j+1) )
    return retval

def add(pos, offset):
    """ Adds two board positions together """
    return (pos[0] + offset[0], pos[1] + offset[1])

def validPos(pos, offset = (0,0)):
    """ Is this position + offset a valid board position?"""
    newx, newy = add(pos, offset)
    return (newx >= 1 and newx <= 8 and newy >= 1 and newy <= 8)

def moveGenerator(board, myPiece, firstMove):
    """Generates legal board moves. Doesn't find multiple-jumps. """
    retval = []
    empties = getEmpties(board)
    if firstMove:
        if len(empties) == 0: # I'm first!
            if myPiece == "O":
                retval.extend( [(4,4), (5,5), (1,1), (8,8)] )
            else:
                retval.extend( [(5,4), (4,5), (1,8), (8,1)] )
        else: # I'm second
            # get one of the 4 (or less) surrounding pieces
            openPos = empties[0] # better be just one
            for i,j in [(-1,0), (+1,0), (0, -1), (0, +1)]:
                if validPos(openPos, (i,j)):
                    retval.append( add(openPos, (i,j)) )
    else:
        # find all moves, and add them to list
        for i in range(1,9):
            for j in range(1,9):
                if board[i-1][j-1] == myPiece:
                    for a,b in [(0, -2),(+2,-2), (+2, 0),(+2, +2),
                                (0, +2),(-2, +2),(-2, 0),(-2, -2)]:
                        p, q = i, j   # a starting place
                        move = [i, j] # first part of move
                        while 1: # still jumps to make
                            if validPos((p,q), (a,b)):
                                x,y = add((p,q),(a,b))
                                if board[x-1][y-1] == '':
                                    bx, by = add( (p,q), (x,y) )
                                    bx, by = bx/2, by/2
                                    if board[bx-1][by-1] == otherPiece(myPiece):
                                        move.extend( [x,y] )
                                        # jump some more?
                                        p, q = x, y
                                    else:
                                        break
                                else:
                                    break
                            else:
                                break
                        if len(move) > 2:
                            retval.append( move )
    return retval

def formatMove(move):
    """ Formats a list of positions into a jump() string. """
    movestr = "jump(%d,%d" % (move[0], move[1])
    while 1:
        x1, y1, x2, y2 = move[:4]
        movestr += ",%d,%d" % (x2, y2)
        move = move[2:]
        if len(move) < 4:
            break
    movestr += ")"
    return movestr

class KonanePlayer(Brain):
    """
    A simple Random Konane Player. Note that the rep of board is
    zero-based, but all other places is one's based.
    For use with PyrobotSimulator and KonaneWorld.py and
    PyrobotRobot.py (a TCPRobot from pyrobot/robot/symbolic.py)
    """
    def setup(self):
        if self.robot.id == 0:
            self.myPiece = "O"
        else:
            self.myPiece = "X"
        self.firstMove = 1
        self.turn = 1
        print "Welcome to Konane, Hawaiian Checkers!"
        print "Red O or X on the board indicates that it"
        print "is that shape's move."
        print "Jumps must occur in a straight line."
        print "A human can play, or start two Pyro's up,"
        print "and connect onto two different ports using"
        print "PyrobotRobot60000 and PyrobotRobot60001."

    def step(self):
        if self.robot.whosMove != self.robot.id:
            time.sleep(1)
            return
        board = self.robot.board
        moves = moveGenerator(board, self.myPiece, self.firstMove)
        self.firstMove = 0
        if len(moves) > 0:
            # Here is where you would go through the possible
            # moves and pick the best one.
            # I'm just going to pick a random one:
            move = moves[int(len(moves) * random.random())]
            if len(move) == 2: # remove the piece
                self.robot.play("remove(%d,%d)" % move)
                print self.turn, "remove(%d,%d)" % move
                self.robot.play("done")
            else: # jumps
                movestr = formatMove(move)
                print self.turn, movestr
                self.robot.play(movestr)
                self.robot.play("done")
            self.turn += 1
        else:
            print "You win!"
            self.pleaseStop() # request to stop running brain

def INIT(engine):
    return KonanePlayer("Random Konane Player", engine)