[{{mminutes}}:{{sseconds}}] X
Пользователь приглашает вас присоединиться к открытой игре игре с друзьями .
PyPylolo
(1)       Используют 4 человека

Комментарии

Ни одного комментария.
Написать тут
Описание:
PyPyhaha
Автор:
nerwator
Создан:
8 марта 2024 в 14:27 (текущая версия от 10 апреля 2024 в 07:42)
Публичный:
Нет
Тип словаря:
Фразы
В этом режиме перемешиваться будут не слова, а целые фразы, разделенные переносом строки.
Содержание:
1 from tkinter import *
2 from scripts.utils import read_config_file
3 cfg = read_config_file()
4 root = Tk()
5 root.geometry('{0}x{1}'.format(cfg['info_box_size']['width'], cfg['info_box_size']['height']))
6 root.title('PokerStarsHelper')
7 root.configure(background='ivory3')
8 lab = Label(root, anchor="w", justify=LEFT, font=("Arial", 18))
9 lab.pack(fill="both", expand=True)
10 def update_label(text):
11 lab.configure(text=text)
12 root.update()
13 from abc import ABC, abstractmethod
14 class PokerTableRecognizer(ABC):
15 @abstractmethod
16 def detect_hero_step(self):
17 Based on the area under hero's cards,
18 we determine whether hero should make a move
19 @abstractmethod
20 def detect_hero_cards(self):
21 pass
22 @abstractmethod
23 def detect_table_cards(self):
24 @abstractmethod
25 def find_total_pot(self):
26 @abstractmethod
27 def get_dealer_button_position(self):
28 determine who is closer to the dealer button
29 @abstractmethod
30 def get_empty_seats(self, players_info):
31 find players whose places are currently vacant
32 @abstractmethod
33 def get_so_players(self, players_info):
34 find players who are not currently in the game
35 @abstractmethod
36 def find_players_bet(self, players_info):
37 from PIL import Image
38 import numpy as np
39 import cv2
40 from mss import mss
41 from pokerstars_recognition import PokerStarsTableRecognizer
42 from utils import read_config_file, set_window_size, remove_cards, data_concatenate
43 from equity import calc_equity
44 from info_box import update_label
45 sct = mss()
46 config = read_config_file()
47 set_window_size()
48 table_data = []
49 while True:
50 updated_table_data = []
51 monitor = {'top': 80, 'left': 70, 'width': config['table_size']['width'],
52 'height': config['table_size']['height']}
53 img = Image.frombytes('RGB', (config['table_size']['width'], config['table_size']['height']),
54 sct.grab(monitor).rgb)
55 img = cv2.cvtColor(np.array(img), cv2.COLOR_BGR2RGB)
56 recognizer = PokerStarsTableRecognizer(img, config)
57 hero_step = recognizer.detect_hero_step()
58 if hero_step:
59 hero_cards = recognizer.detect_hero_cards()
60 table_cards = recognizer.detect_table_cards()
61 total_pot = recognizer.find_total_pot()
62 updated_table_data.append([hero_cards, table_cards, total_pot])
63 if table_data == updated_table_data:
64 pass
65 else:
66 table_data = updated_table_data
67 deck = remove_cards(hero_cards, table_cards)
68 equity = calc_equity(deck, hero_cards, table_cards)
69 players_info = recognizer.get_dealer_button_position()
70 players_info = recognizer.get_empty_seats(players_info)
71 players_info = recognizer.get_so_players(players_info)
72 players_info = recognizer.assign_positions(players_info)
73 players_info = recognizer.find_players_bet(players_info)
74 text = data_concatenate(hero_cards, table_cards, total_pot, equity, players_info)
75 update_label(text)
76 deck = [eval7.Card(card) for card in deck]
77 table_cards = [eval7.Card(card) for card in table_cards]
78 hero_cards = [eval7.Card(card) for card in hero_cards]
79 max_table_cards = 5
80 win_count = 0
81 for _ in range(iters):
82 np.random.shuffle(deck)
83 num_remaining = max_table_cards - len(table_cards)
84 draw = deck[:num_remaining+2]
85 opp_hole, remaining_comm = draw[:2], draw[2:]
86 player_hand = hero_cards + table_cards + remaining_comm
87 opp_hand = opp_hole + table_cards + remaining_comm
88 player_strength = eval7.evaluate(player_hand)
89 opp_strength = eval7.evaluate(opp_hand)
90 if player_strength > opp_strength:
91 win_count += 1
92 win_prob = (win_count / iters) * 100
93 return round(win_prob, 2)
94 import yaml
95 import os
96 import cv2
97 import numpy as np
98 from time import sleep
99 from math import sqrt
100 def read_config_file(filename='config.yaml'):
101 """
102 Parameters:
103 filename (str): config file name
104 Returns: loaded_data (dict)
105 """
106 with open(filename, 'r') as stream:
107 loaded_data = yaml.safe_load(stream)
108 return loaded_data
109 def sort_bboxes(bounding_boxes, method):
110 """
111 Parameters:
112 bounding_boxes(list of lists of int): bounding_boxes in [x_0, y_0, x_1, y_1] format
113 method(int): the method of sorting bounding boxes.
114 It can be left-to-right, bottom-to-top or top-to-bottom
115 Returns:
116 bounding_boxes (list of tuple of int): sorted bounding boxes.
117 Each bounding box presented in [x_0, y_0, x_1, y_1] format
118 ""
119 methods = ['left-to-right', 'bottom-to-top', 'top-to-bottom']
120 if method not in methods:
121 raise ValueError("Invalid method. Expected one of: %s" % methods)
122 else:
123 if method == 'left-to-right':
124 bounding_boxes.sort(key=lambda tup: tup[0])
125 elif method == 'bottom-to-top':
126 bounding_boxes.sort(key=lambda tup: tup[1], reverse=True)
127 elif method == 'top-to-bottom':
128 bounding_boxes.sort(key=lambda tup: tup[1], reverse=False)
129 return bounding_boxes
130 def mse(img, benchmark_img):
131 """
132 the 'Mean Squared Error' between two images that
133 is the sum of the squared difference between the two images.
134 NOTE: the two images must have the same dimension.
135 Parameters:
136 img(numpy.ndarray): image of a part of the table
137 benchmark_img(numpy.ndarray): benchmark image.
138 This image read from the folder.
139 Returns:
140 err (float): the error between two images
141 """
142 err = np.sum((img.astype("float") - benchmark_img.astype("float")) ** 2)
143 err /= float(img.shape[0] * img.shape[1])
144 return err
145 def image_comparison(img, benchmark_img, color_of_img):
146 """
147 Parameters:
148 img(numpy.ndarray): image of a part of the table
149 benchmark_img(str): path to benchmark image
150 color_of_img(int): set in which format to read the image.
151 It can be cv2.IMREAD_COLOR or cv2.IMREAD_GRAYSCALE
152 Returns:
153 err (float): the error between two images
154 """
155 colors = [cv2.IMREAD_COLOR, cv2.IMREAD_GRAYSCALE]
156 if color_of_img not in colors:
157 raise ValueError("Invalid method. Expected one of: %s" % colors)
158 benchmark_img = cv2.imread(benchmark_img, color_of_img)
159 res_img = cv2.resize(img, (benchmark_img.shape[1], benchmark_img.shape[0]))
160 if color_of_img == cv2.IMREAD_GRAYSCALE:
161 res_img = cv2.cvtColor(res_img, cv2.COLOR_BGR2GRAY)
162 err = mse(res_img, benchmark_img)
163 return err
164 def thresholding(img, value_1, value_2):
165 """
166 Parameters:
167 img(numpy.ndarray): image of a part of the table
168 value_1(int): threshold value
169 value_2(int): the maximum value that is assigned
170 to pixel values that exceed the threshold value
171 Returns: binary_img(numpy.ndarray)
172 """
173 img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
174 _, binary_img = cv2.threshold(img, value_1, value_2, cv2.THRESH_BINARY)
175 return binary_img
176 def table_part_recognition(img, directory, color_of_img):
177 """
178 Parameters:
179 img(numpy.ndarray): image of a part of the table
180 directory(str): path to the template images
181 color_of_img(int): set in which format to read the image.
182 It can be cv2.IMREAD_COLOR or cv2.IMREAD_GRAYSCALE
183 Returns:
184 table_part(str): recognized suit, value (J, K etc.), pot etc.
185 """
186 err_dict = {}
187 for full_image_name in os.listdir(directory):
188 image_name = full_image_name.split('.')[0]
189 err = image_comparison(img, directory + full_image_name, color_of_img)
190 err_dict[image_name] = err
191 table_part = min(err_dict, key=err_dict.get)
192 return table_part
193 def convert_contours_to_bboxes(contours, min_height, min_width):
194 """
195 convert contours to bboxes, also remove all small bounding boxes
196 Parameters:
197 contours (tuple): each individual contour is a numpy array
198 of (x, y) coordinates of boundary points of the object
199 contours(list of tuples of int): bounding boxes suits
200 and values (J, K etc.) in [x, y, w, h] format
201 Returns:
202 cards_bboxes(list of lists of int): bounding boxes suits
203 and values (J, K etc.) in [x_0, y_0, x_1, y_1] format
204 """
205 bboxes = [cv2.boundingRect(contour) for contour in contours]
206 cards_bboxes = []
207 for i in range(0, len(bboxes)):
208 x, y, w, h = bboxes[i][0], bboxes[i][1], \
209 bboxes[i][2], bboxes[i][3]
210 if h >= min_height and w >= min_width:
211 contour_coordinates = [x - 1, y - 1, x + w + 1, y + h + 1]
212 cards_bboxes.append(contour_coordinates)
213 return cards_bboxes
214 def card_separator(bboxes, separators):
215 """
216 determine which bounding box belongs to which card
217 Parameters:
218 bboxes(list of lists of int): bounding boxes suits and values (J, K etc.)
219 separators(list of int): contains values where the card ends
220 Returns:
221 sorted_dct(dict) key - card number, value - bounding boxes
222 """
223 dct = {}
224 for bbox in bboxes:
225 for separator in separators:
226 if bbox[2] < separator:
227 dct[separators.index(separator)] = dct.get(separators.index(separator), []) + [bbox]
228 break
229 sorted_dct = {key: value for key, value in sorted(dct.items(), key=lambda item: int(item[0]))}
230 return sorted_dct
231 def find_by_template(img, path_to_image):
232 """
233 Object detection using a "template".
234 Parameters:
235 img(numpy.ndarray): image of a part of the table/of the entire table
236 path_to_image(str): the path to a template image
237 Returns:
238 max_val(float): largest value with the most likely match
239 max_loc(tuple of int): location with the largest value.
240 Location is presented in (x, y) format
241 """
242 template_img_gray = cv2.imread(path_to_image, 0)
243 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
244 result = cv2.matchTemplate(img_gray, template_img_gray,
245 cv2.TM_CCOEFF_NORMED)
246 (min_val, max_val, min_loc, max_loc) = cv2.minMaxLoc(result)
247 return max_val, max_loc
248 def load_images(directory):
249 """
250 Parameters:
251 directory(str): path to specific directory
252 Returns:
253 images(list of numpy.ndarray): images of a part of the table
254 file_names(list of str): the name of the files in the folder
255 """
256 images = [cv2.imread(directory + file) for file in sorted(os.listdir(directory))]
257 file_names = [file for file in sorted(os.listdir(directory))]
258 return images, file_names
259 def find_closer_point(players_coordinates, button_coordinates):
260 """
261 find the distance between two points and find the minimum distance
262 Parameters:
263 players_coordinates(dict): key - player number, value - player coordinates
264 button_coordinates(tuple): Coordinates are presented in (x, y) format
265 Returns:
266 player_with_button(int): the number of the player who is closest
267 to the buttonthe number of the player who is closest to the button
268 """
269 distance_dict = {}
270 for player, player_coordinates in players_coordinates.items():
271 distance = sqrt((player_coordinates[0] - button_coordinates[0]) ** 2
272 + (player_coordinates[1] - button_coordinates[1]) ** 2)
273 distance_dict[player] = distance
274 player_with_button = min(distance_dict, key=distance_dict.get)
275 return player_with_button
276 def remove_cards(hero_cards, table_cards):
277 """
278 Parameters:
279 hero_cards(list of str): cards that belong to the hero
280 table_cards(list of str): cards that are on the table
281 Returns:
282 all_cards(list of str): all other cards, not including cards that are on the table and hero cards
283 for card in hero_cards+table_cards:
284 all_cards.remove(card)
285 return all_cards
286 def set_window_size():
287 """
288 set the application window in the right place and with the right size
289 """
290 sleep(3)
291 cmd = 'wmctrl -r :ACTIVE: -e 0,0,0,1100,900'
292 os.system(cmd)
293 def data_concatenate(hero_hand, table_cards, total_pot, equity, players_info):
294 """
295 information from all lists, dictionaries are added to one common line
296 """
297 text_players_info = ''
298 for key, value in players_info.items():
299 value = 'no bet found' if value == '' else value
300 text_players_info += str(key) + ':' + str(value) + '
'
301 table_cards = ['no cards on the table'] if table_cards == [] else table_cards
302 text = 'Hero hand: ' + ' '.join(hero_hand) + '
' + 'Board: ' + ' '.join(table_cards) + '
' +
303 'Pot: ' + total_pot + '
' + 'Equity: ' + str(equity) + '%' + '
' + \
304 '------------------------------' + '
' + text_players_info
305 return text
306 import cv2
307 import numpy as np
308 from scripts.table_recognition import PokerTableRecognizer
309 from scripts.utils import sort_bboxes, thresholding, card_separator, table_part_recognition, \
310 convert_contours_to_bboxes, find_by_template, find_closer_point, read_config_file
311 class PokerStarsTableRecognizer(PokerTableRecognizer):
312 def __init__(self, img, cfg):
313 """
314 Parameters:
315 img(numpy.ndarray): image of the whole table
316 cfg (dict): config file
317 """
318 self.img = img
319 self.cfg = cfg
320 def detect_hero_step(self):
321 """
322 Based on the area under hero's cards,
323 we determine whether hero should make a move
324 Returns:
325 Boolean Value(True or False): True, if hero step now
326 """
327 res_img = self.img[self.cfg['hero_step_define']['y_0']:self.cfg['hero_step_define']['y_1'],
328 self.cfg['hero_step_define']['x_0']:self.cfg['hero_step_define']['x_1']]
329 hsv_img = cv2.cvtColor(res_img, cv2.COLOR_BGR2HSV_FULL)
330 mask = cv2.inRange(hsv_img, np.array(self.cfg['hero_step_define']['lower_gray_color']),
331 np.array(self.cfg['hero_step_define']['upper_gray_color']))
332 count_of_white_pixels = cv2.countNonZero(mask)
333 return True if count_of_white_pixels > self.cfg['hero_step_define']['min_white_pixels'] else False
334 def detect_cards(self, separators, sort_bboxes_method, cards_coordinates, path_to_numbers, path_to_suits):
335 """
336 Parameters:
337 separators(list of int): contains values where the card ends
338 sort_bboxes_method(str): defines how we will sort the contours.
339 It can be left-to-right, bottom-to-top, top-to-bottom
340 cards_coordinates(str): path to cards coordinates
341 path_to_numbers(str): path where located numbers (J, K etc.)
342 path_to_suits(str) : path where located suits
343 Returns:
344 cards_name(list of str): name of the cards
345 """
346 cards_name = []
347 img = self.img[self.cfg[cards_coordinates]['y_0']:self.cfg[cards_coordinates]['y_1'],
348 self.cfg[cards_coordinates]['x_0']:self.cfg[cards_coordinates]['x_1']]
349 binary_img = thresholding(img, 200, 255)
350 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
351 bounding_boxes = convert_contours_to_bboxes(contours, 10, 2)
352 bounding_boxes = sort_bboxes(bounding_boxes, method=sort_bboxes_method)
353 cards_bboxes_dct = card_separator(bounding_boxes, separators)
354 for _, cards_bboxes in cards_bboxes_dct.items():
355 if len(cards_bboxes) == 3:
356 cards_bboxes = [cards_bboxes[0]]
357 elif len(cards_bboxes) == 0:
358 return []
359 elif len(cards_bboxes) > 3:
360 raise ValueError("The number of bounding boxes should not be more than 3!")
361 card_name = ''
362 for key, bbox in enumerate(cards_bboxes):
363 color_of_img, directory = (cv2.IMREAD_COLOR, self.cfg['paths'][path_to_suits]) if key == 0 \
364 else (cv2.IMREAD_GRAYSCALE, self.cfg['paths'][path_to_numbers])
365 res_img = img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
366 card_part = table_part_recognition(res_img, directory, color_of_img)
367 card_name = card_part + 'T' if len(cards_bboxes) == 1 else card_name + card_part
368 cards_name.append(card_name[::-1])
369 return cards_name
370 def detect_hero_cards(self):
371 """
372 Returns:
373 cards_name(list of str): name of the hero's cards
374 """
375 separators = [self.cfg['hero_cards']['separator_1'], self.cfg['hero_cards']['separator_2']]
376 sort_bboxes_method = 'bottom-to-top'
377 cards_coordinates = 'hero_cards'
378 path_to_numbers = 'hero_cards_numbers'
379 path_to_suits = 'hero_cards_suits'
380 cards_name = self.detect_cards(separators, sort_bboxes_method, cards_coordinates,
381 path_to_numbers, path_to_suits)
382 return cards_name
383 def detect_table_cards(self):
384 """
385 Returns:
386 cards_name(list of str): name of the cards on the table
387 """
388 separators = [self.cfg['table_cards']['separator_1'], self.cfg['table_cards']['separator_2'],
389 self.cfg['table_cards']['separator_3'], self.cfg['table_cards']['separator_4'],
390 self.cfg['table_cards']['separator_5']]
391 sort_bboxes_method = 'top-to-bottom'
392 cards_coordinates = 'table_cards'
393 path_to_numbers = 'table_cards_numbers'
394 path_to_suits = 'table_cards_suits'
395 cards_name = self.detect_cards(separators, sort_bboxes_method, cards_coordinates,
396 path_to_numbers, path_to_suits)
397 return cards_name
398 def find_total_pot(self):
399 """
400 Returns:
401 number(str): number with total pot
402 """
403 img = self.img[self.cfg['pot']['y_0']:self.cfg['pot']['y_1'],
404 self.cfg['pot']['x_0']:self.cfg['pot']['x_1']]
405 _, max_loc = find_by_template(img, self.cfg['paths']['pot_image'])
406 bet_img = img[max_loc[1] - 3:max_loc[1] + self.cfg['pot']['height'],
407 max_loc[0] + self.cfg['pot']['pot_template_width']:
408 max_loc[0] + self.cfg['pot']['pot_template_width'] + self.cfg['pot']['width']]
409 binary_img = thresholding(bet_img, 105, 255)
410 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
411 bounding_boxes = convert_contours_to_bboxes(contours, 3, 1)
412 bounding_boxes = sort_bboxes(bounding_boxes, method='left-to-right')
413 number = ''
414 for bbox in bounding_boxes:
415 number_img = bet_img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
416 symbol = table_part_recognition(number_img, self.cfg['paths']['pot_numbers'], cv2.IMREAD_GRAYSCALE)
417 number += symbol
418 return number
419 def get_dealer_button_position(self):
420 """
421 determine who is closer to the dealer button
422 Returns:
423 player_info(dict): here is information about all players as it becomes available
424 """
425 player_info = {key: value for key in range(1, 7) for value in ['']}
426 players_coordinates = self.cfg['player_center_coordinates']
427 _, button_coordinates = find_by_template(self.img, self.cfg['paths']['dealer_button'])
428 player_with_button = find_closer_point(players_coordinates, button_coordinates)
429 player_info[player_with_button] = 'dealer_button'
430 return player_info
431 def get_missing_players(self, players_info, path_to_template_img, flag):
432 """
433 find players who are currently absent for various reasons
434 Parameters:
435 players_info(dict): key - player number, value - '' - if the player is in the game;
436 '-' - if a player's seat is available; '-so-' - if the player is absent
437 path_to_template_img(str): the path to the images where the benchmark images are located
438 flag(str): It can be - and -so-
439 Returns:
440 players_info(dict): info about players
441 """
442 players_coordinates = self.cfg['players_coordinates']
443 players_for_checking = [key for key, value in players_info.items() if value == '']
444 for player, bbox in players_coordinates.items():
445 if player != 1 and player in players_for_checking:
446 player_img = self.img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
447 max_val, _ = find_by_template(player_img, self.cfg['paths'][path_to_template_img])
448 if max_val > 0.8:
449 players_info[player] = flag
450 return players_info
451 def get_empty_seats(self, players_info):
452 """
453 find players whose places are currently vacant
454 """
455 path_to_template_img = 'empty_seat'
456 flag = '-'
457 players_info = self.get_missing_players(players_info, path_to_template_img, flag)
458 return players_info
459 def get_so_players(self, players_info):
460 """
461 find players who are not currently in the game
462 """
463 path_to_template_img = 'sitting_out'
464 flag = '-so-'
465 players_info = self.get_missing_players(players_info, path_to_template_img, flag)
466 return players_info
467 def assign_positions(self, players_info):
468 """
469 assign each player one of six positions if the player in the game
470 Parameters:
471 players_info(dict): info about players in {1:'', 2: 'dealer_button',3:'-so-' etc. } format
472 Returns:
473 players_info(dict): info about players in {1: 'BB', 2: 'SB', 3: '-so-' etc. } format
474 """
475 busy_seats = [k for k, v in players_info.items() if v != '-' and v != '-so-']
476 exist_positions = ['BTN', 'SB', 'BB', 'UTG', 'MP', 'CO']
477 del exist_positions[3:3 + (6 - len(busy_seats))]
478 player_with_button = [k for k, v in players_info.items() if v == 'dealer_button'][0]
479 for index, player_number in enumerate(
480 busy_seats[busy_seats.index(player_with_button):] + busy_seats[:busy_seats.index(player_with_button)]):
481 if len(busy_seats) == 2:
482 position = 'SB' if index == 0 else 'BB'
483 players_info[player_number] = position
484 else:
485 players_info[player_number] = exist_positions[index]
486 return players_info
487 def find_players_bet(self, players_info):
488 """
489 Parameters:
490 players_info(dict): info about players in {1:'BTN', 2:'SB', 3:'BB' etc. } format
491 Returns:
492 updated_players_info(dict): info about players in {'Hero':'BTN', 'SB':'', 'BB':'50' etc. } format
493 """
494 players_bet_location = self.cfg['players_bet']
495 updated_players_info = {'Hero': players_info[1]}
496 for i, location_coordinates in players_bet_location.items():
497 if players_info[i] not in ('-so-', '-'):
498 bet_img = self.img[location_coordinates[1]:location_coordinates[3],
499 location_coordinates[0]:location_coordinates[2]]
500 binary_img = thresholding(bet_img, 105, 255)
501 contours, _ = cv2.findContours(binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
502 bounding_boxes = convert_contours_to_bboxes(contours, 3, 1)
503 bounding_boxes = sort_bboxes(bounding_boxes, method='left-to-right')
504 number = ''
505 for bbox in bounding_boxes:
506 number_img = bet_img[bbox[1]:bbox[3], bbox[0]:bbox[2]]
507 symbol = table_part_recognition(number_img, self.cfg['paths']['pot_numbers'], cv2.IMREAD_GRAYSCALE)
508 number += symbol
509 updated_players_info[players_info[i]] = number
510 else:
511 updated_players_info[i] = players_info[i]
512 return updated_players_info
513 import sys
514 sys.path.append('./redis')
515 sys.path.append('./bots')
516 sys.path.append('./main_functions')
517 sys.path.append('./PyPokerEngine')
518 import os
519 import time
520 import pickle
521 import argparse
522 from redis import Redis
523 from rq import Queue
524 from operator import add
525 from u_generate import gen_rand_bots, gen_decks
526 from u_training_games import run_generation_games
527 from u_neuroevolution import select_next_gen_bots, get_best_ANE_earnings
528 from u_formatting import prep_gen_dirs, get_gen_flat_params
529 if __name__ == '__main__':
530 """ #### PARSE ARGUMENTS, AND PROCESS #### """
531 parser = argparse.ArgumentParser(description='')
532 parser.add_argument('--simul_id', default = -1, type=int, help='Id of the simulation. Should be defined to avoid overwriting past simulations.')
533 parser.add_argument('--network', default='6max_full', type=str, help='Neural network architecture to use. [hu_first, hu_second, 6max_single, 6max_full]')
534 parser.add_argument('--redis_host', default='local', type=str, help='Address of redis host. [local, ec2, *]')
535 parser.add_argument('--train_env', default='default', type=str, help='Environment used in training (table size, game type and opponents). Default will select according to the neural network [default, hu_cash_mixed, 6max_sng_ruler, 6max_sng_mixed]')
536 parser.add_argument('--ga_ini_gen', default=0, type=int, help='The generation at which to start the genetic algorithm. Used to resume an interrupted simulation.')
537 parser.add_argument('--ga_nb_gens', default=250, type=int, help='Number of generations of the genetic algorithm.')
538 parser.add_argument('--ga_popsize', default=70, type=int, help='Population size of the genetic algorithm.')
539 parser.add_argument('--norm_fitfunc', default=True, type=bool, help='Wether to use normalization scheme in the genetic algorithm\'s fitness function.')
540 parser.add_argument('--worker_timeout', default=800, type=int, help='Time in seconds before a job taken by a worker and not returned is considered to have timed out.')
541 parser.add_argument('--max_hands', default=300, type=int, help='Maximum number of hands played in a tournament. If attained, the agent is considered to have lost.')
542 parser.add_argument('--small_blind', default=10, type=int, help='Initial small blind amount. If tournament, the blind structure will overrule.')
543 parser.add_argument('--ini_stack', default=1500, type=int, help='Initial stack of the players.')
544 parser.add_argument('--nb_opps', default=4, type=int, help= 'Number of different tables against which to train')
545 parser.add_argument('--log_dir', default='../data/training_data', type=str, help='The path of the file where the simulation data will be stored.')
546 parser.add_argument('--verbose', default=True, type= bool, help = 'Whether to print detailled run time information.')
547 args = parser.parse_args()
548 if args.redis_host == 'local':
549 REDIS_HOST = '127.0.0.1'
550 elif args.redis_host == 'ec2':
551 REDIS_HOST = '172.31.42.99'
552 else:
553 REDIS_HOST = args.redis_host
554 my_network = args.network
555 my_normalize = args.norm_fitfunc
556 my_timeout = args.worker_timeout
557 simul_id = args.simul_id
558 ga_popsize = args.ga_popsize
559 nb_generations = args.ga_nb_gens
560 ini_gen = args.ga_ini_gen
561 nb_hands = args.max_hands
562 sb_amount = args.small_blind
563 ini_stack = args.ini_stack
564 log_dir = args.log_dir
565 train_env = args.train_env
566 verbose = args.verbose
567 nb_opps = args.nb_opps #TODO, move to simul arch def
568 my_nb_games = nb_opps*4 #TODO, move to simul arch def
569 if my_network in ['hu_first','hu_second']: #TODO handle differently.
570 my_nb_games=1
571 if train_env == 'default':
572 if my_network in ['hu_first','hu_second']:
573 train_env = 'hu_cash_mixed'
574 elif my_network == '6max_single':
575 train_env = '6max_sng_ruler'
576 elif my_network =='6max_full':
577 train_env = '6max_sng_mixed'
578 """ #### SETTING UP #### """
579 # Start redis host and clear queue
580 redis = Redis(REDIS_HOST)
581 q = Queue(connection=redis, default_timeout=my_timeout)
582 for j in q.jobs:
583 j.cancel()
584 if ini_gen==0:
585 # if this is a new simulation (not resuming one)
586 # Generate the first generation of bots randomly
587 gen_dir = log_dir+'/simul_'+str(simul_id)+'/gen_'+str(ini_gen)
588 gen_rand_bots(gen_dir, network=my_network, ga_popsize = ga_popsize, overwrite=False)
589 # Write configuration details to text file
590 file = open(log_dir+'/simul_'+str(simul_id)+"/configuration_details.txt",'w')
591 file.write("## CONFIGURATION DETAILS ##

")
592 file.write(str(args))
593 file.close()
594 """ #### STARTING TRAINING #### """
595 if verbose: print('## Starting training session ##')
596 for gen_id in range(ini_gen, nb_generations):
597 if verbose: print('
Starting generation: ' + str(gen_id))
598 #Define generation's directory. Create one except if already existing
599 gen_dir = log_dir+'/simul_'+str(simul_id)+'/gen_'+str(gen_id)
600 if not os.path.exists(gen_dir):
601 os.makedirs(gen_dir)
602 #Prepare all decks of the generation
603 cst_decks = gen_decks(gen_dir = gen_dir, overwrite=False, nb_hands=nb_hands, nb_games=my_nb_games)
604 """#### RUN THE GAMES ####"""
605 time_start_games = time.time()
606 all_earnings = run_generation_games(gen_dir = gen_dir, ga_popsize = ga_popsize, my_network = my_network,
607 my_timeout = my_timeout, train_env = train_env, cst_decks=cst_decks,
608 ini_stack=ini_stack, sb_amount = sb_amount, nb_hands = nb_hands,
609 q = q)
610 # Saving earnings
611 for i, earnings in enumerate(all_earnings):
612 with open(gen_dir+'/bots/'+str(i+1)+'/earnings.pkl', 'wb') as f:
613 pickle.dump(earnings, f)
614 if verbose:
615 ## Getting best earnings
616 best_earnings = get_best_ANE_earnings(all_earnings = all_earnings, BB=2*sb_amount, ga_popsize = ga_popsize, nb_opps=nb_opps,normalize=my_normalize)
617 print("Best agent score: {}".format(["%.2f" % earning for earning in best_earnings.values()]))
618 # Getting average earning of deepbots agents
619 avg_earnings=[0,]*len(all_earnings[0].values())
620 for i in range(ga_popsize):
621 avg_earnings= list(map(add, avg_earnings, all_earnings[i].values()))
622 avg_earnings= [el/ga_popsize for el in avg_earnings]
623 print("Average agent's scores: {}".format(["%.2f" % earning for earning in avg_earnings]))
624 time_end_games = time.time()
625 if verbose: print("Running games took {:.0f} seconds.".format(time_end_games-time_start_games))
626 time_start_evo = time.time()
627 gen_flat_params = get_gen_flat_params(dir_=gen_dir)
628 next_gen_dir = log_dir+'/simul_'+str(simul_id)+'/gen_'+str(gen_id+1)
629 prep_gen_dirs(dir_=next_gen_dir)
630 next_gen_bots_flat = select_next_gen_bots(log_dir=log_dir, simul_id=simul_id, gen_id=gen_id, all_earnings=all_earnings, BB=2*sb_amount,
631 ga_popsize=ga_popsize, gen_flat_params = gen_flat_params, nb_gens = nb_generations,
632 network=my_network, nb_opps=nb_opps, normalize=my_normalize, verbose = verbose)
633 for bot_id in range(1, ga_popsize+1):
634 if not os.path.exists(next_gen_dir+'/bots/'+str(bot_id)):
635 os.makedirs(next_gen_dir+'/bots/'+str(bot_id))
636 deepbot_flat = next_gen_bots_flat[bot_id-1]
637 with open(next_gen_dir+'/bots/'+str(bot_id)+'/bot_'+str(bot_id)+'_flat.pkl', 'wb') as f:
638 pickle.dump(deepbot_flat, f)
639 time_end_evo = time.time()
640 if verbose: print("Evolution took {:.0f} seconds.".format(time_end_evo-time_start_evo))
641 import sys
642 sys.path.append('./PyPokerEngine')
643 sys.path.append('./bots')
644 sys.path.append('./main_functions')
645 import pickle
646 import argparse
647 from pypokerengine.api.game import setup_config, start_poker
648 from u_formatting import get_full_dict
649 from bot_TestBot import TestBot
650 from bot_CallBot import CallBot
651 from bot_PStratBot import PStratBot
652 from bot_DeepBot import DeepBot
653 from bot_EquityBot import EquityBot
654 from bot_ManiacBot import ManiacBot
655 from bot_CandidBot import CandidBot
656 from bot_ConservativeBot import ConservativeBot
657 if __name__ == '__main__':
658 """ #### PARSE ARGUMENTS #### """
659 parser = argparse.ArgumentParser(description='')
660 parser.add_argument('--agent_file', default = '../data/trained_agents_git/6max_single/gen_250/bots/1/bot_1_flat.pkl', type=str, help='Path to file of a trained agent (in flat format).')
661 parser.add_argument('--network', default = '6max_single', type=str, help='Neural network of the agent. [hu_first, hu_second, 6max_single, 6max_full]')
662 parser.add_argument('--table_ind', default = 0, type = int, help='Indice of the table of opponents to play against. For more details open this file')
663 parser.add_argument('--max_hands', default=300, type=int, help='Maximum number of hands played in a tournament. If attained, the agent is considered to have lost.')
664 args = parser.parse_args()
665 agent_file = args.agent_file
666 my_network = args.network
667 table_ind = args.table_ind
668 max_hands = args.max_hands
669 ##Possible opponent tables##
670 opp_tables = [[PStratBot, PStratBot, PStratBot, PStratBot, PStratBot],
671 [CallBot, CallBot, CallBot, ConservativeBot, PStratBot],
672 [ConservativeBot, ConservativeBot, ConservativeBot, CallBot, PStratBot],
673 [ManiacBot, ManiacBot, ManiacBot, ConservativeBot, PStratBot],
674 [PStratBot, PStratBot, PStratBot, CallBot, ConservativeBot]]
675 ref_full_dict = DeepBot(network=my_network).full_dict
676 """ #### PREPARE AND PLAY GAME #### """
677 print('## Starting ##')
678 ## LOADING AGENT ##
679 with open(agent_file, 'rb') as f:
680 deepbot_flat = pickle.load(f)
681 deepbot_dict = get_full_dict(all_params = deepbot_flat, ref_full_dict = ref_full_dict)
682 deepbot = DeepBot(full_dict = deepbot_dict, network=my_network)
683 ## PREPARING GAME ##
684 config = setup_config(max_round=max_hands, initial_stack=1500, small_blind_amount=10)
685 nb_opps, plays_per_blind = 5, 90
686 for ind in range(nb_opps):
687 config.register_player(name="p-"+str(ind+1), algorithm=opp_tables[table_ind][ind]())
688 config.register_player(name="deepbot", algorithm=deepbot)
689 blind_structure={0*plays_per_blind:{'ante':0, 'small_blind':10},\
690 1*plays_per_blind:{'ante':0, 'small_blind':15},\
691 2*plays_per_blind:{'ante':0, 'small_blind':25},\
692 3*plays_per_blind:{'ante':0, 'small_blind':50},\
693 4*plays_per_blind:{'ante':0, 'small_blind':100},\
694 5*plays_per_blind:{'ante':25, 'small_blind':100},\
695 6*plays_per_blind:{'ante':25, 'small_blind':200},\
696 7*plays_per_blind:{'ante':50, 'small_blind':300},\
697 8*plays_per_blind:{'ante':50, 'small_blind':400},\
698 9*plays_per_blind:{'ante':75, 'small_blind':600},}
699 config.set_blind_structure(blind_structure)
700 game_result, last_two_players, deepbot_rank = start_poker(config, verbose=True, return_last_two = True, return_deepbot_rank = True)
701 earning =- 1
702 deepbot_rank += 1
703 earning=-1
704 ini_hero_pos = 5
705 if deepbot.round_count==max_hands:
706 print('Game could not finish in max number of hands')
707 earning = -1
708 else:
709 if "deepbot" in last_two_players:
710 earning=1
711 if game_result['players'][ini_hero_pos]['stack']>0:
712 earning=3
713 print("
Finishing place: "+str(deepbot_rank))
714 print("Tokens earned: "+str(earning))

Связаться
Выделить
Выделите фрагменты страницы, относящиеся к вашему сообщению
Скрыть сведения
Скрыть всю личную информацию
Отмена