|  | @@ -14,15 +14,101 @@ from curses import KEY_RIGHT, KEY_LEFT, KEY_UP, KEY_DOWN
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  # import AI models into sandbox
 | 
	
		
			
				|  |  |  from models.AIBob import AIBob
 | 
	
		
			
				|  |  | -AIBob = AIBob() # BoB
 | 
	
		
			
				|  |  | +from models.AIAlice import AIAlice
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -# extract name from players
 | 
	
		
			
				|  |  | -def extract_name(p):
 | 
	
		
			
				|  |  | -    name = AIBob.extractName() # BoB
 | 
	
		
			
				|  |  | -    return name
 | 
	
		
			
				|  |  | +bots = ['AIBoB','AIAlice']
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ######################################################################3
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +class BoxSelector:
 | 
	
		
			
				|  |  | +    def __init__(self, bots):
 | 
	
		
			
				|  |  | +        self.TEXTBOX_WIDTH = 50
 | 
	
		
			
				|  |  | +        self.TEXTBOX_HEIGHT = 6
 | 
	
		
			
				|  |  | +        self.PAD_WIDTH = 400
 | 
	
		
			
				|  |  | +        self.PAD_HEIGHT = 10000
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def pick(self):
 | 
	
		
			
				|  |  | +        self._init_curses()
 | 
	
		
			
				|  |  | +        self._create_pad()
 | 
	
		
			
				|  |  | +        windows = self._make_textboxes()
 | 
	
		
			
				|  |  | +        picked = self._select_textbox(windows)
 | 
	
		
			
				|  |  | +        self._end_curses()
 | 
	
		
			
				|  |  | +        return picked
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def _init_curses(self):
 | 
	
		
			
				|  |  | +        self.stdscr = curses.initscr()
 | 
	
		
			
				|  |  | +        curses.noecho()
 | 
	
		
			
				|  |  | +        curses.cbreak()
 | 
	
		
			
				|  |  | +        curses.curs_set(0)
 | 
	
		
			
				|  |  | +        self.stdscr.keypad(1)
 | 
	
		
			
				|  |  | +        curses.start_color()
 | 
	
		
			
				|  |  | +        curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_GREEN)
 | 
	
		
			
				|  |  | +        curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK)
 | 
	
		
			
				|  |  | +        self.stdscr.bkgd(curses.color_pair(2))
 | 
	
		
			
				|  |  | +        self.stdscr.refresh()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def _end_curses(self):
 | 
	
		
			
				|  |  | +        curses.nocbreak()
 | 
	
		
			
				|  |  | +        self.stdscr.keypad(0)
 | 
	
		
			
				|  |  | +        curses.echo()
 | 
	
		
			
				|  |  | +        curses.endwin()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def _create_pad(self):
 | 
	
		
			
				|  |  | +        self.pad = curses.newpad(self.PAD_HEIGHT, self.PAD_WIDTH)
 | 
	
		
			
				|  |  | +        self.pad.box()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def _make_textboxes(self):
 | 
	
		
			
				|  |  | +        maxy, maxx = self.stdscr.getmaxyx()
 | 
	
		
			
				|  |  | +        windows = []
 | 
	
		
			
				|  |  | +        i = 1
 | 
	
		
			
				|  |  | +        for s in bots:
 | 
	
		
			
				|  |  | +            windows.append(self.pad.derwin(self.TEXTBOX_HEIGHT,
 | 
	
		
			
				|  |  | +                    self.TEXTBOX_WIDTH, i, self.PAD_WIDTH//2-self.TEXTBOX_WIDTH//2))
 | 
	
		
			
				|  |  | +            i += self.TEXTBOX_HEIGHT
 | 
	
		
			
				|  |  | +        for k in range(len(windows)):
 | 
	
		
			
				|  |  | +            windows[k].box()
 | 
	
		
			
				|  |  | +            windows[k].addstr(4, 4, '{0:X} - {1}'.format(k, bots[k]))
 | 
	
		
			
				|  |  | +        return windows
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def _center_view(self, window):
 | 
	
		
			
				|  |  | +        cy, cx = window.getbegyx()
 | 
	
		
			
				|  |  | +        maxy, maxx = self.stdscr.getmaxyx()
 | 
	
		
			
				|  |  | +        self.pad.refresh(cy, cx, 1, maxx//2 - self.TEXTBOX_WIDTH//2, maxy-1, maxx-1)
 | 
	
		
			
				|  |  | +        return (cy, cx)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def _select_textbox(self, windows):
 | 
	
		
			
				|  |  | +        topy, topx = self._center_view(windows[0])
 | 
	
		
			
				|  |  | +        current_selected = 0
 | 
	
		
			
				|  |  | +        last = 1
 | 
	
		
			
				|  |  | +        top_textbox = windows[0]
 | 
	
		
			
				|  |  | +        while True:
 | 
	
		
			
				|  |  | +            windows[current_selected].bkgd(curses.color_pair(1))
 | 
	
		
			
				|  |  | +            windows[last].bkgd(curses.color_pair(2))
 | 
	
		
			
				|  |  | +            maxy, maxx = self.stdscr.getmaxyx()
 | 
	
		
			
				|  |  | +            cy, cx = windows[current_selected].getbegyx()
 | 
	
		
			
				|  |  | +            if ((topy + maxy - self.TEXTBOX_HEIGHT) <= cy):
 | 
	
		
			
				|  |  | +                top_textbox = windows[current_selected]
 | 
	
		
			
				|  |  | +            if topy >= cy + self.TEXTBOX_HEIGHT:
 | 
	
		
			
				|  |  | +                top_textbox = windows[current_selected]
 | 
	
		
			
				|  |  | +            if last != current_selected:
 | 
	
		
			
				|  |  | +                last = current_selected
 | 
	
		
			
				|  |  | +            topy, topx = self._center_view(top_textbox)
 | 
	
		
			
				|  |  | +            c = self.stdscr.getch()
 | 
	
		
			
				|  |  | +            if c == ord('0') or c == 258: # KEY_UP
 | 
	
		
			
				|  |  | +                if current_selected >= len(windows)-1:
 | 
	
		
			
				|  |  | +                    current_selected = 0 
 | 
	
		
			
				|  |  | +                else:
 | 
	
		
			
				|  |  | +                    current_selected += 1
 | 
	
		
			
				|  |  | +            elif c == ord('1') or c == 259: # KEY_DOWN
 | 
	
		
			
				|  |  | +                if current_selected <= 0:
 | 
	
		
			
				|  |  | +                    current_selected = len(windows)-1
 | 
	
		
			
				|  |  | +                else:
 | 
	
		
			
				|  |  | +                    current_selected -= 1
 | 
	
		
			
				|  |  | +            elif c == ord('q') or c == 27: # ESC
 | 
	
		
			
				|  |  | +                break
 | 
	
		
			
				|  |  | +            elif c == curses.KEY_ENTER or c == 10:
 | 
	
		
			
				|  |  | +                return int(current_selected)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  # translate a thought into a text
 | 
	
		
			
				|  |  |  def text_to_thought(move):
 | 
	
		
			
				|  |  |      if move == KEY_UP:
 | 
	
	
		
			
				|  | @@ -66,14 +152,15 @@ def startGame(win, food, snake, evol, record, max_moves):
 | 
	
		
			
				|  |  |      moves = 0
 | 
	
		
			
				|  |  |      score = 0
 | 
	
		
			
				|  |  |      thought = "WAKING UP..."
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -######################################################################3
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    name = AIBob.extractName() # BoB
 | 
	
		
			
				|  |  | -    move = AIBob.makeMove(win, None, food, snake) # BoB
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -######################################################################3
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +    choice = BoxSelector(bots).pick()
 | 
	
		
			
				|  |  | +    if not choice:
 | 
	
		
			
				|  |  | +        choice = 0 # BoB
 | 
	
		
			
				|  |  | +    name = bots[choice]
 | 
	
		
			
				|  |  | +    if name == "AIBoB":
 | 
	
		
			
				|  |  | +        bot = AIBob() # BoB
 | 
	
		
			
				|  |  | +    else:
 | 
	
		
			
				|  |  | +        bot = AIAlice() #Alice
 | 
	
		
			
				|  |  | +    move = bot.makeMove(win, None, food, snake) # first move
 | 
	
		
			
				|  |  |      moves += 1
 | 
	
		
			
				|  |  |      thought = text_to_thought(move)
 | 
	
		
			
				|  |  |      # build game
 | 
	
	
		
			
				|  | @@ -84,17 +171,19 @@ def startGame(win, food, snake, evol, record, max_moves):
 | 
	
		
			
				|  |  |          win.timeout(150 - int((len(snake)/5) + int(len(snake)/10)%120)) # if > length: > speed
 | 
	
		
			
				|  |  |          prevMove = move  
 | 
	
		
			
				|  |  |          event = win.getch()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -######################################################################3
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        move = AIBob.makeMove(win, prevMove, food, snake) # BoB
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -######################################################################3
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        move = bot.makeMove(win, prevMove, food, snake) # rest of movements
 | 
	
		
			
				|  |  |          moves += 1
 | 
	
		
			
				|  |  |          thought = text_to_thought(move)
 | 
	
		
			
				|  |  |          move = move if event == -1 else event
 | 
	
		
			
				|  |  |          if move != KEY_UP and move != KEY_DOWN and move != KEY_LEFT and move != KEY_RIGHT : # ANY KEY for pause
 | 
	
		
			
				|  |  | +            if move == 27: # ESC
 | 
	
		
			
				|  |  | +                breaked = ' GAME FINISHED: GOOD BYE! ;-)'
 | 
	
		
			
				|  |  | +                win.addstr(9, 9, breaked)
 | 
	
		
			
				|  |  | +                win.getch()
 | 
	
		
			
				|  |  | +                curses.nocbreak()
 | 
	
		
			
				|  |  | +                curses.echo()
 | 
	
		
			
				|  |  | +                curses.endwin()
 | 
	
		
			
				|  |  | +                break
 | 
	
		
			
				|  |  |              move = -1 # pause
 | 
	
		
			
				|  |  |              paused = ' GAME PAUSED: PRESS -SPACEBAR- TO RESTORE'
 | 
	
		
			
				|  |  |              win.addstr(9, 9, paused)
 |