File size: 4,959 Bytes
e498243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import chess
import random
import streamlit as st

def cleanup_output(text, prompt, extra_len):
        section = text[len(prompt):]
        st.write("Proposed Move: " + section)
        valid_letters = ['A','a','B','b','C','c','D','d','E','e','F','f','G','g','H','h']
        valid_pieces = ['p','P','k','K','q','Q','r','R','b','B', 'n', 'N']
        valid_numbers = ['1','2','3','4','5','6','7','8']

        #if there are any syntatically moves in this string for pieces
        countr = 0
        while countr < len(section) - 3:
          if(section[countr] in valid_pieces and section[countr + 1] in valid_letters and section[countr + 2] in valid_numbers):
            #print(section[countr:countr+3])
            return ' ' + section[countr:countr+3]
          countr+=1
        
        #variant for capturing!
        countr = 0
        while countr < len(section) - 4:
          if(section[countr] in valid_pieces and section[countr + 1] == 'x' and section[countr + 2] in valid_letters and section[countr + 3] in valid_numbers):
            #print(section[countr:countr+3])
            return ' ' + section[countr:countr+5]
          countr+=1

        #same as moves but for pawns
        countr = 0
        while countr < len(section) - 2:
          if(section[countr] in valid_letters and section[countr+1] in valid_numbers):
            #print(section[countr:countr+2])
            return ' ' + section[countr:countr+2]
          countr+=1

        #variant for capturing!
        countr = 0
        while countr < len(section) -4:
          if(section[countr] in valid_letters and section[countr+1] == 'x' and section[countr+2] in valid_letters and section[countr + 3] in valid_numbers):
            #print(section[countr:countr+2])
            return ' ' + section[countr:countr+4]
          countr+=1
        
        return ' e8'

class AInstance:
    def __init__(self, type, generator):
        self.type = type
        self.game_end = False
        self.generator = generator        

    #All this does it take the gamestate and add the ai-generated result to it
    def move(self, game_state):
        if(self.type == "gpt2-medium-chess"):
            prompt = "1-0 2700 1350 " + game_state
            extra_len = 7
        else:
            prompt = game_state
            extra_len = 5
        countr = 0
        while True:
            generated_text = self.generator(prompt, max_length=len(prompt) + extra_len, num_return_sequences=1)[0]['generated_text']
            selected_move = cleanup_output(generated_text, prompt, extra_len)
            
            #if this move is valid then return it
            proposed_board = game_state + selected_move
            if(verify_move(proposed_board)):
                return proposed_board
            countr+=1
            #goes fifty times until the AInstance object flags itself as "ended" (fundamentally unable to make a valid move)
            if(countr > 50):
                self.game_end = True
                break

    def check_if_end(self):
        return self.game_end

def verify_move(string):
    board = chess.Board()
    st.write("Board: " + string + "\n")
    for move in string.split():
      #if this move makes no sense it will return false and the game will try again to generate a good move
      try:
        board.push_san(move)
      except:
        return False
    if(board.is_valid):
      return True
    return False

def check_mate(string):
  #simulates mate idk
    if(random.randrange(0,100) == 4):
        st.write("H")
        return True
    return False

def print_game(string):
    st.write("Some kind of visualization for the chess board based on this string: " + string)

def make_move(instance, game_state):
    st.write(instance.type + "'s move")
    return_state = game_state
    return_state = instance.move(game_state)
    game_ongoing = True
    if(instance.check_if_end()):
        st.write("This player claims they can't make a valid move after 50 tries: " + instance.type)
        game_ongoing = False
    if(check_mate(return_state)):
        st.write("This player claims mates: " +  instance.type)
        game_ongoing = False
    return(return_state, game_ongoing)


def main():
    if(random.randint(0,1) == 1):
        white = AInstance("gpt2", generator)
        black = AInstance("gpt2-medium-chess", generator2)
        st.write("Gpt2 is White and Gpt2 Optimized is Black\n")
    else:
        white = AInstance("gpt2-medium-chess", generator2)
        black = AInstance("gpt2", generator)
        st.write("Gpt2 is Black and Gpt2 Optimized is White\n")

    game_state = "e4 e5"
    game_ongoing = True
    while game_ongoing:
        game_state, game_ongoing = make_move(white, game_state)
        if not game_ongoing:
            print_game(game_state)
            break
        game_state, game_ongoing = make_move(black, game_state)
        if not game_ongoing:
            print_game(game_state)
            break
main()