読者です 読者をやめる 読者になる 読者になる

リバーシ頑張ってみた

PEP8なんて知りません(キリッ
pythonに浸かりきってない人のpython


英語のスペルミスは・・・あるかもね〜かもね〜orz

# -*- encoding: utf8 -*-

class Field(object):
    def __init__(self):
        self.width = 8
        self.height = 8

        self.black = 1
        self.white = -1
        self.space = 0

        self.reset()

    def __repr__(self):
        s = '.ox'
        ret = ''
        for y in range(8):
           for x in range(8):
               pos = self.get_position(x, y)
               ret += s[self.field[pos]]
           ret += '\n'
        return ret

    def reset(self):
        self.field = [self.space for i in range(self.width * self.height)]
        
        pos = self.get_position(3, 3)
        self.field[pos] = self.white
        pos = self.get_position(4, 4)
        self.field[pos] = self.white
        pos = self.get_position(4, 3)
        self.field[pos] = self.black
        pos = self.get_position(3, 4)
        self.field[pos] = self.black
        
   
    def get_position(self, x, y):
        return x + self.width * y
 
    def get_stone(self, x, y):
        index = self.get_position(x, y)
        return self.field[index]
    
    def reverse_line(self, x, y, vx, vy, stone):
        pos = self.get_position(x, y)
        f = self.field
        if stone != -f[pos + vx + vy * self.width]:
            return None
 
        for i in range(2, 8):
            move_x = x + vx * i
            move_y = y + vy * i
            if not 0 <= move_x < 8 or not 0 <= move_y < 8:
                return None
            pos = self.get_position(move_x, move_y)
            if f[pos] == 0:
                return None
            elif f[pos] == stone:
                return (vx, vy)
     
    def is_put_stone(self, x, y, stone):
        vec_tup = ((-1, -1), ( 0, -1), ( 1, -1),
                   (-1,  0),           ( 1,  0),
                   (-1,  1), ( 0,  1), ( 1,  1))
        reverse_list = []
        for vx, vy in vec_tup:
            ret = self.reverse_line(x, y, vx, vy, stone)
            if ret:
                reverse_list.append(ret)
        return reverse_list

    def reverse_stone(self, x, y, stone, reverse_list):
        pos = self.get_position(x, y)
        f = self.field
        f[pos] = stone
        for vx, vy in reverse_list:
            i = 1
            while f[pos + i * vx + self.width * i * vy] == -stone:
                f[pos + i * vx + self.width * i * vy] = stone
                i += 1

    def exist_space(self):
        return 0 in self.field

    def exist_stone(self, stone):
        return stone in self.field

    def count_stone(self):
        count = [0, 0, 0]
        for val in self.field:
            count[val] += 1
        del count[0]
        return tuple(count)
            
    def check_turn(self, stone):
        for i, v in enumerate(self.field):
            if v == self.space:
                if self.is_put_stone(i % self.width, i / self.width, stone):
                    return True
        return False

def main():
    f = Field()
    step = [(2,3,1), (4,2,-1), (5,3,1), (2,4,-1), (3,5,1), (2,2,-1), (1,3,1), (3,2,-1), (3,1,1)]
    print f

    for x, y, stone in step:
        reverse_list = f.is_put_stone(x, y, stone)
        print x, y, "black" if stone == f.black else "white"
        if reverse_list:
            f.reverse_stone(x, y, stone, reverse_list)
            
            if not f.exist_stone(-stone):
                print "%s win!" % "black" if stone == f.black else "white"
                break

            if not f.exist_space():
                black, white = f.count_stone()
                print "%d vs %d", 
                if black == white:
                    print "drow!"
                else:
                    print "black" if black > white else "white"
                break
            
            if not f.check_turn(-stone):
                print "skip!"
                if not f.check_turn(stone):
                    print "can't put stone both."
                    break
            else:
                # change turn
                pass
            print f
        else:
            print "error: can't put stone! (%d, %d)" % (x, y)
            break
    print f

if __name__ == '__main__':
    main()