Pulling this repo

#1
.gitignore DELETED
@@ -1 +0,0 @@
1
- interface_experiment.py
 
 
README.md CHANGED
@@ -11,5 +11,3 @@ license: cc-by-4.0
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
14
-
15
- ![Alt text](mermaid-diagram-2024-01-16-104433.png)
 
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
__pycache__/game_database.cpython-311.pyc DELETED
Binary file (2.97 kB)
 
__pycache__/logger.cpython-311.pyc DELETED
Binary file (4.43 kB)
 
app.py CHANGED
@@ -1,172 +1,4 @@
1
-
2
- import chess
3
- import random
4
  import streamlit as st
5
- from transformers import pipeline
6
-
7
- from game_database import GameDatabase
8
- from logger import Logger
9
-
10
- generator2 = pipeline('text-generation', model='BlueSunflower/gpt2-medium-chess')
11
- generator = pipeline('text-generation', model='gpt2')
12
-
13
- def cleanup_output(text, prompt):
14
- section = text[len(prompt):len(prompt) + 7]
15
- st.write("Proposed Move: " + section)
16
- valid_letters = ['A','a','B','b','C','c','D','d','E','e','F','f','G','g','H','h']
17
- valid_pieces = ['p','P','k','K','q','Q','r','R','b','B', 'n', 'N']
18
- valid_numbers = ['1','2','3','4','5','6','7','8']
19
-
20
- #if there are any syntatically moves in this string for pieces
21
- countr = 0
22
- while countr < 4:
23
- if(section[countr] in valid_pieces and section[countr + 1] in valid_letters and section[countr + 2] in valid_numbers):
24
- #print(section[countr:countr+3])
25
- return ' ' + section[countr:countr+3]
26
- countr+=1
27
-
28
- #variant for capturing!
29
- countr = 0
30
- while countr < len(section) - 4:
31
- 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):
32
- #print(section[countr:countr+3])
33
- return ' ' + section[countr:countr+5]
34
- countr+=1
35
-
36
- #same as moves but for pawns
37
- countr = 0
38
- while countr < 5:
39
- if(section[countr] in valid_letters and section[countr+1] in valid_numbers):
40
- #print(section[countr:countr+2])
41
- return ' ' + section[countr:countr+2]
42
- countr+=1
43
-
44
- #variant for capturing!
45
- countr = 0
46
- while countr < len(section) -4:
47
- 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):
48
- #print(section[countr:countr+2])
49
- return ' ' + section[countr:countr+4]
50
- countr+=1
51
-
52
- return ' e8'
53
-
54
- class AInstance:
55
- def __init__(self, type, generator):
56
- self.type = type
57
- self.game_end = False
58
- self.generator = generator
59
-
60
- #All this does it take the gamestate and add the ai-generated result to it
61
- def move(self, game_state):
62
- if(type == "BlueSunflower/gpt2-medium-chess"):
63
- prompt = "1-0 2700 1350 " + game_state
64
- else:
65
- prompt = game_state
66
- countr = 0
67
- while True:
68
- generated_text = self.generator(prompt, max_length=len(prompt) + 10, num_return_sequences=1)[0]['generated_text']
69
- selected_move = cleanup_output(generated_text, prompt)
70
-
71
- #if this move is valid then return it
72
- proposed_board = game_state + selected_move
73
- if(verify_move(proposed_board)):
74
- return proposed_board, countr
75
- countr+=1
76
- #goes fifty times until the AInstance object flags itself as "ended" (fundamentally unable to make a valid move)
77
- if(countr > 50):
78
- self.game_end = True
79
- break
80
-
81
- def check_if_end(self):
82
- return self.game_end
83
-
84
- def verify_move(string): #Given all moves so far, this checks if any moves are illegal.
85
- board = chess.Board()
86
- st.write("Board: " + string)
87
- for move in string.split():
88
- #if this move makes no sense it will return false and the game will try again to generate a good move
89
- try:
90
- board.push_san(move)
91
- except:
92
- st.write("Invalid Move\n")
93
- return False
94
- if(board.is_valid):
95
- st.write("Valid Move\n")
96
- return True
97
- return False
98
-
99
- def check_mate(string): #Am confusion
100
- #simulates mate idk
101
- if(random.randrange(0,100) == 4):
102
- st.write("H")
103
- return True
104
- return False
105
-
106
- def print_game(string):
107
- st.write("Some kind of visualization for the chess board based on this string: " + string)
108
-
109
- def make_move(instance, game_state):
110
- print("\n" + instance.type + "s's move")
111
- return_state = game_state
112
- return_state, countr = instance.move(game_state)
113
- game_ongoing = True
114
- if(instance.check_if_end()):
115
- st.write("This player claims countr > 50: " + instance.type)
116
- game_ongoing = False
117
- if(check_mate(return_state)):
118
- st.write("This player claims mates: " + instance.type)
119
- game_ongoing = False
120
- return(return_state, game_ongoing, countr)
121
-
122
-
123
- def main():
124
-
125
- player_1 = "gpt2"
126
- player_2 = "gpt2-medium-chess"
127
-
128
- if(random.randrange(0,1)):
129
- white = AInstance(player_1, generator)
130
- black = AInstance(player_2, generator2)
131
- st.write("Gpt2 is White and Gpt2 Optimized is Black")
132
- else:
133
- white = AInstance(player_2, generator2)
134
- black = AInstance(player_1, generator)
135
- st.write("Gpt2 is Black and Gpt2 Optimized is White")
136
-
137
- onetime_logger = Logger(white.type, black.type) #Logger.model_1 should be white and vice versa
138
-
139
- game_state = "e4 e5"
140
- game_ongoing = True
141
-
142
- moves = 0
143
- while game_ongoing:
144
- game_state, game_ongoing, white_cheat_count = make_move(white, game_state)
145
- for i in range(white_cheat_count):
146
- onetime_logger.add_cheat()
147
- onetime_logger.add_legal_move(game_state)
148
-
149
- if not game_ongoing:
150
- print_game(game_state)
151
- break
152
- game_state, game_ongoing, black_cheat_count = make_move(black, game_state)
153
- for i in range(black_cheat_count):
154
- onetime_logger.add_cheat()
155
- onetime_logger.add_legal_move(game_state)
156
- if not game_ongoing:
157
- print_game(game_state)
158
- break
159
-
160
- #testing code
161
- moves += 1
162
- if moves >= 2:
163
- break
164
-
165
- onetime_logger.add_checkmate(player_1) #here for testing purposes
166
- finished_game = onetime_logger.return_formatted_game()
167
- onetime_db = GameDatabase()
168
- onetime_db.add_game(finished_game)
169
 
170
- onetime_db.display_game(0)
171
- if __name__ == "__main__":
172
- main()
 
 
 
 
1
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
+ x = st.slider('Select a value')
4
+ st.write(x, 'squared is', x * x)
 
architecture_diagram.md DELETED
@@ -1,25 +0,0 @@
1
- ```mermaid
2
- ---
3
- config:
4
- flowchart:
5
- defaultRenderer: elk
6
- ---
7
- flowchart LR
8
- interface(Model \n Interface)
9
- model(Chosen Model)
10
- logger("Logger\nget_stockfish_results()")
11
- coordinator(Game \n Coordinator)
12
- database("Game Database \n display_analytics()")
13
-
14
- coordinator --model_vs_model(model_1: str, model_2:str)-->interface
15
- coordinator --human_vs_model(model name: str) -->interface
16
-
17
- interface --send_move(model_name, UCI_notation) \n returns response-->model
18
-
19
- interface --create(model_1: str, model_2: str) \n creates a few logger for each game--> logger
20
- interface --add_legal_move(UCI_notation_of_game: str)-->logger
21
- interface--add_cheat(cheater_name: str)-->logger
22
- interface--add_checkmate(winner_name: str)-->logger
23
-
24
- logger --return_formatted_game(game_in_UCI: str, cheat_log: [int])-->database
25
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
game_database.py DELETED
@@ -1,101 +0,0 @@
1
- import chess
2
- import matplotlib.pyplot as plt
3
- import pandas as pd
4
- import streamlit as st
5
- from typing import Dict
6
- from logger import Logger
7
- import time
8
- import numpy as np
9
-
10
- class GameDatabase:
11
- def __init__(self):
12
- self.db = []
13
- pass
14
-
15
- def add_game(self, game: Dict[str, str]):
16
- self.db.append(game)
17
-
18
- def display_game(self, game_num: int): #Displays analytics for a specific game
19
- game = self.db[game_num]
20
-
21
- fig, axs = plt.subplots(2,2)
22
- fig.tight_layout()
23
- width = 0.4
24
-
25
- def list_sets_graph(data_list: [], axs_pos: [], title, width = 0.4):
26
- white_data = data_list[::2]
27
- black_data = data_list[1::2]
28
- x_w = np.arange(len(white_data))
29
- x_b = np.arange(len(black_data))
30
-
31
- axs[axs_pos[0], axs_pos[1]].set_xticks(x_w, [x for x in range(len(white_data))])
32
- axs[axs_pos[0], axs_pos[1]].bar(x_w - (width/2), white_data, width, color = "navajowhite")
33
- axs[axs_pos[0], axs_pos[1]].bar(x_b + (width/2), black_data, width, color = "saddlebrown")
34
- axs[axs_pos[0], axs_pos[1]].legend(["White", "Black"])
35
- axs[axs_pos[0], axs_pos[1]].set_title(title)
36
-
37
-
38
-
39
- #plot time per move, with data for each model
40
- time_title = "Seconds Per Move"
41
- list_sets_graph(game[time_title], axs_pos=[0,0], title=time_title)
42
-
43
- #plot cheating per model
44
- cheat_title = "Cheat Attempts Per Move"
45
- list_sets_graph(game["Cheat Attempts"], axs_pos=[1,0], title = cheat_title)
46
-
47
- #stockfish analysis of each player over time
48
-
49
-
50
- #plt.show()
51
- st.pyplot(fig)
52
-
53
-
54
- def display_tournament(self): #Displays analytics for the entire tournament
55
-
56
- df = pd.DataFrame(self.db)
57
-
58
- #heatmap of tournament winrates
59
-
60
- #bar chart of tournament winrates
61
- win_results = df["Winner"].value_counts()
62
- print(win_results.rank())
63
-
64
- names = ["steve", "bob", "emily"]
65
- nums = [1,2,3]
66
-
67
- fig, axs = plt.subplots(2,1)
68
- axs[0].plot(win_results)
69
- axs[1].bar(names, nums)
70
-
71
- st.pyplot(fig)
72
-
73
-
74
-
75
- if __name__ == "__main__":
76
- test_logger = Logger("ChessGPT", "ChatGPT")
77
- test_logger.add_cheat()
78
- time.sleep(1)
79
- test_logger.add_legal_move("e4")
80
- time.sleep(1)
81
- test_logger.add_legal_move("e4 e6")
82
- time.sleep(2)
83
- test_logger.add_legal_move("e4 e6 Nf3")
84
- test_logger.add_checkmate("ChessGPT")
85
- #test_logger.add_legal_move("e4 e5")
86
- formatted = test_logger.return_formatted_game()
87
-
88
- test_logger_2 = Logger("ChessGPT", "BERT")
89
- test_logger_2.add_checkmate("BERT")
90
- formatted_2 = test_logger_2.return_formatted_game()
91
-
92
- test_logger_3 = Logger("ChessGPT", "BERT")
93
- test_logger_3.add_checkmate("ChessGPT")
94
- formatted_3 = test_logger_3.return_formatted_game()
95
-
96
- db = GameDatabase()
97
- db.add_game(formatted)
98
- db.add_game(formatted_2)
99
- db.add_game(formatted_3)
100
-
101
- db.display_game(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
interface_experiment.py DELETED
@@ -1,13 +0,0 @@
1
- import transformers
2
-
3
- model_id = "BlueSunflower/gpt2-medium-chess"
4
- text_generator = transformers.pipeline("text-generation", model = model_id)
5
- input_text = "1-0 2995 3110 1.e4 e5 2.Nf3 Nc6"
6
-
7
- for i in range(5):
8
- generated = text_generator(input_text, max_new_tokens = 10)[0]["generated_text"]
9
- new_string = str(generated).replace(input_text, "")
10
- move = new_string.split(" ", maxsplit=1)[1]
11
- input_text += move
12
- print(input_text)
13
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
logger.py DELETED
@@ -1,95 +0,0 @@
1
- import requests
2
- import re
3
- import time
4
-
5
- class Logger:
6
- def __init__(self, model_1: str, model_2: str): #Model 1 should be white
7
- self.model_1 = model_1
8
- self.model_2 = model_2
9
- self.current_moves = ""
10
-
11
- self.cheat_attempts = [0]
12
-
13
- self.winner = ""
14
- self.checkmate = False
15
-
16
- self.seconds_per_move = []
17
- self.prev_end_time = time.time()
18
-
19
- self.stockfish_results = []
20
-
21
- #Interface with the Model Interface
22
- def add_legal_move(self, current_moves: str): #current_moves should be all moves so far, in UCI notation
23
- if self.checkmate:
24
- raise RuntimeError("This game has already reached checkmate")
25
- else:
26
- self.current_moves = current_moves
27
- self.cheat_attempts.append(0)
28
-
29
- current_time = time.time()
30
- self.seconds_per_move.append(current_time - self.prev_end_time)
31
- self.prev_end_time = current_time
32
-
33
- def add_cheat(self):
34
- if self.checkmate:
35
- raise RuntimeError("This game has already reached checkmate")
36
- else:
37
- self.cheat_attempts[-1] += 1
38
-
39
- def add_checkmate(self, winner_name: str):
40
- if winner_name != self.model_1 and winner_name != self.model_2:
41
- raise RuntimeError("Not a valid winner for this logger")
42
- else:
43
- self.winner = winner_name
44
- self.checkmate = True
45
-
46
-
47
-
48
- #Internal Work
49
- def get_stockfish_results(self, prev_state: str, current_state: str, depth: int = 5) -> float: #Takes current and previous FEN states. Can be refactored to only need one UCI current state
50
- #returns the stockfish analysis of the last move as a positive float
51
- #Example URL: https://stockfish.online/api/stockfish.php?fen=r2q1rk1/ppp2ppp/3bbn2/3p4/8/1B1P4/PPP2PPP/RNB1QRK1 w - - 5 11&depth=5&mode=eval
52
- current_FEN = "?fen=" + current_state
53
- prev_FEN = "?fen=" + prev_state
54
-
55
- endpoint = "https://stockfish.online/api/stockfish.php"
56
- current_extra = current_FEN + "&depth=" + str(depth) + "&mode=eval"
57
- prev_extra = prev_FEN + "&depth=" + str(depth) + "&mode=eval"
58
- current_response = requests.get(endpoint + current_extra)
59
- prev_response = requests.get(endpoint + prev_extra)
60
-
61
- current_string = str(current_response.json())
62
- prev_string = str(prev_response.json())
63
-
64
- current_score = float(re.findall(r"-?\d*\.*\d+", current_string)[0]) #Positive means white is winning and vice versa
65
- prev_score = float(re.findall(r"-?\d*\.*\d+", prev_string)[0])
66
- #Add something to make sure it's that player's turn to make the move?
67
-
68
- return abs(current_score) - abs(prev_score) #Positive numbers mean the player that made the move is better off
69
- def format_game(self):
70
- pass
71
-
72
- #Interface with game_database
73
- def return_formatted_game(self):
74
-
75
- if self.winner == "":
76
- raise RuntimeError("Game is not yet completed")
77
- pass
78
-
79
- else:
80
- game = {"Model 1": self.model_1,
81
- "Model 2": self.model_2,
82
- "Winner": self.winner,
83
- "UCI": self.current_moves,
84
- "Cheat Attempts": self.cheat_attempts,
85
- "Seconds Per Move": self.seconds_per_move,
86
- "Stockfish Results": self.stockfish_results}
87
- return game
88
-
89
- #Testing section
90
- if __name__ == "__main__":
91
- new_logger = Logger("ChessGPT", "ChatGPT")
92
- current_board = "r2q1rk1/1pp2ppp/3bbn2/p2p4/8/1B1P4/PPP2PPP/RNB1QRK1 w - - 5 11" #make sure to include the additional notation at the end
93
- prev_board = "r2q1rk1/ppp2ppp/3bbn2/3p4/8/1B1P4/PPP2PPP/RNB1QRK1 w - - 5 11"
94
- print(str(new_logger.get_stockfish_results(prev_board, current_board)))
95
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
mermaid-diagram-2024-01-16-104433.png DELETED
Binary file (37.9 kB)
 
requirements.txt DELETED
@@ -1,7 +0,0 @@
1
- #To download requirements, use 'python -m pip install -r requirements.txt'
2
- python-chess==1.1.0
3
- matplotlib==3.8.2
4
- requests==2.28.2
5
- pandas==1.5.3
6
- transformers==4.36.2
7
- torch==2.1.2