def addMovie(self, sender, movie): self.movies.append(movie) row = self.moviesFlexTable.getRowCount() self.moviesFlexTable.setText(row, 1, movie.category) self.moviesFlexTable.setText(row, 2, movie.name) self.moviesFlexTable.setText(row, 3, movie.rating) # Adds buttons for remove, edit, save and cancel removeMovieButton = Button("x") editMovieButton = Button("Edit") saveButton = Button("Save") cancelButton = Button("Cancel") # Save and cancel are hidden by default saveButton.setVisible(False) cancelButton.setVisible(False) # Add buttons to row buttons = HorizontalPanel() buttons.add(removeMovieButton) buttons.add(editMovieButton) buttons.add(cancelButton) buttons.add(saveButton) self.moviesFlexTable.setWidget(row, 0, buttons) def removeMovieButton_Click(sender): self.remote.deleteMovie((movie.name, movie.category), self) removeMovieButton.addClickListener(removeMovieButton_Click) def editMovieButton_Click(sender): # Add textboxes and listbox editMovieButton.setVisible(False) cancelButton.setVisible(True) saveButton.setVisible(True) editCategory = TextBox() editName = TextBox() editRating = ListBox(False) for i in range(self.MAX_RATING + 1): editRating.addItem(str(i)) # Variable width textboxes catlen = len(movie.category) namelen = len(movie.name) if (catlen > 8): editCategory.setWidth(str(catlen*10) + "px") else: editCategory.setWidth("80px") if (namelen > 8): editName.setWidth(str(namelen*10) + "px") else: editName.setWidth("80px") self.moviesFlexTable.setWidget(row, 1, editCategory) self.moviesFlexTable.setWidget(row, 2, editName) self.moviesFlexTable.setWidget(row, 3, editRating) editCategory.setText(movie.category) editName.setText(movie.name) editRating.setSelectedIndex(movie.rating) editMovieButton.addClickListener(editMovieButton_Click) def saveButton_Click(sender): catText = self.moviesFlexTable.getWidget(row, 1) nameText = self.moviesFlexTable.getWidget(row, 2) ratingList = self.moviesFlexTable.getWidget(row, 3) newCategory = catText.getText().trim().lower() newCategory = newCategory[0].upper() + newCategory[1:] newName = nameText.getText().trim() newRating = ratingList.getSelectedIndex() if not self.verifyInputs(newName, newCategory): return # Removes temporarily to check for duplicates self.movies.remove(movie) newMovie = Movie(newName, newCategory, newRating) if newMovie in self.movies: Window.alert("'" + newName + "' is already in table.") nameText.selectAll() return self.remote.editMovie((movie.name, movie.category), (newMovie.name, newMovie.category, newMovie.rating), self) saveButton.addClickListener(saveButton_Click) def cancelButton_Click(sender): self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 1)) self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 2)) self.moviesFlexTable.remove(self.moviesFlexTable.getWidget(row, 3)) # Reverts fields to old movie info self.moviesFlexTable.setText(row, 1, movie.category) self.moviesFlexTable.setText(row, 2, movie.name) self.moviesFlexTable.setText(row, 3, movie.rating) cancelButton.setVisible(False) saveButton.setVisible(False) editMovieButton.setVisible(True) cancelButton.addClickListener(cancelButton_Click)
class GridWidget(AbsolutePanel): def __init__(self): self.state = State() self.game_over = False self.TD_CONSTS = {'c3': 0.767944, 'c2': 1.049451, 'c1': 3.074038, 'c6': 0.220823, 'c5': 0.281883, 'c4': 0.605861} AbsolutePanel.__init__(self) StyleSheetCssText(margins) # initialize css... self.welcome_label = HTML('<H2 align="center">Welcome to Meta-Tic-Tac-Toe!</H2><p>Play first by clicking on one of the positions in the middle board or let the AI go first by clicking on "AI first". To change the difficulty click on "Increase/Decrease search depth". Note: if there is a pop-up saying that the script is taking a long time to complete, this is not a bug - the AI is just taking a while to find the next move. Select the option to continue the script.</p>', StyleName='margins_both') self.add(self.welcome_label) self.depthLimit = 3 self.human_first = True self.ai_first = Button("AI first.", self, StyleName='margins_left') self.add(self.ai_first) self.increase_depth = Button("Increase search depth", self) self.decrease_depth = Button("Decrease search depth", self) self.depth_label = HTML("""AI will search to a <a href="#depth_explanation">depth</a> of """ + str(self.depthLimit) +".") self.depth_grid = Grid(StyleName='margins_left') self.depth_grid.resize(1, 3) self.depth_grid.setBorderWidth(2) self.depth_grid.setCellPadding(9) self.depth_grid.setCellSpacing(1) self.add(self.depth_grid) self.depth_grid.setWidget(0, 0, self.decrease_depth) self.depth_grid.setWidget(0, 1, self.depth_label) self.depth_grid.setWidget(0, 2, self.increase_depth) self.new_game = Button("New game", self, StyleName='margins_left') self.add(self.new_game) self.score_label = Label("CURRENT SCORE: Human: %d | AI: %d"% (0,0), StyleName='margins_left') self.add(self.score_label) self.game_over_msg = HTML("", StyleName='margins_left') self.add(self.game_over_msg) # initialize the board grid: self.g=Grid(StyleName='margins_left') self.g.resize(3, 3) self.g.setBorderWidth(2) self.g.setCellPadding(9) self.g.setCellSpacing(1) self.init() self.add(self.g) # initialize the contstants adjustment grid: self.adj_grid = Grid(StyleName='margins_left') self.adj_grid.resize(7, 3) self.adj_grid.setBorderWidth(2) self.adj_grid.setCellPadding(9) self.adj_grid.setCellSpacing(1) self.init_constants_adj_grid() self.add(self.adj_grid) self.max_player = '-1' self.min_player = '-1' self.state_to_grid() def init_constants_adj_grid(self): '''Initializes the grid that allows the TD_CONSTS to be adjusted. ''' self.decr_buttons = {} self.adj_labels = {} self.incr_buttons = {} td_keys = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] self.adj_grid.setWidget(0, 1, HTML('''Adjust the <a href="#utility_function">constants</a> to change<br>the AI's behavior.''')) for i, key in enumerate(td_keys): j = i + 1 self.decr_buttons[key] = Button('<', self) self.adj_grid.setWidget(j, 0, self.decr_buttons[key]) self.incr_buttons[key] = Button('>', self) self.adj_grid.setWidget(j, 2, self.incr_buttons[key]) self.adj_labels[key] = Label("Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.adj_grid.setWidget(j, 1, self.adj_labels[key]) def init(self): '''Initializes the grid on which the game is played. ''' for y_board in range(3): for x_board in range(3): g=Grid() g.resize(3, 3) g.setBorderWidth(2) g.setCellPadding(9) g.setCellSpacing(1) for x_cell in range(3): for y_cell in range(3): b = Button('Play here.', self) b.point = {'x_cell':x_cell, 'y_cell':y_cell, 'y_board': y_board, 'x_board': x_board} g.setWidget(y_cell, x_cell, b) self.add(g) self.g.setWidget(y_board, x_board, g) def start_new_game(self): #g.__init__() nope, can't use this :( self.state = State() self.game_over = False self.depthLimit = 3 self.human_first = True self.ai_first.setVisible(True) # new game, so we make this button visible self.check_win() self.max_player = '-1' self.min_player = '-1' self.state_to_grid() def onClick(self, sender): if sender == self.increase_depth: self.depthLimit += 1 self.depth_label.setHTML("""AI will search to a <a href="#depth_explanation">depth</a> of """ + str(self.depthLimit) +".") if sender == self.decrease_depth: self.depthLimit -= 1 self.depth_label.setHTML("""AI will search to a <a href="#depth_explanation">depth</a> of """ + str(self.depthLimit) +".") if sender == self.new_game: self.start_new_game() self.check_adjusts(sender) if not self.game_over: if sender == self.ai_first and self.min_player == -1: # we only set min_player and max_player when they are not yet initialized self.human_first = False self.max_player = '1' self.min_player = '2' self.state.next_piece[2] = self.max_player self.ai_first.setVisible(False) # can't go first any more so we make it invisible... new_state = ab(self.state, self.TD_CONSTS, depth_limit=self.depthLimit)[1] last_position = find_last_move(self.state, new_state) self.state = new_state self.state_to_grid(prev_x_board=last_position['x_board'], prev_y_board=last_position['y_board'], prev_x_cell=last_position['x_cell'], prev_y_cell=last_position['y_cell'],) if hasattr(sender, 'point'): if self.min_player == -1: # we only set min_player and max_player when they are not yet initialized self.max_player = '2' self.min_player = '1' self.ai_first.setVisible(False) # can't go first any more so we make it invisible... point = sender.point g = self.g.getWidget(point['y_board'], point['x_board']) g.setText(point['y_cell'], point['x_cell'], str(self.min_player)) self.grid_to_state(point) self.check_win() self.state.next_piece[2] = self.max_player new_state = ab(self.state, self.TD_CONSTS, depth_limit=self.depthLimit)[1] last_position = find_last_move(self.state, new_state) self.state = new_state self.state_to_grid(prev_x_board=last_position['x_board'], prev_y_board=last_position['y_board'], prev_x_cell=last_position['x_cell'], prev_y_cell=last_position['y_cell'],) self.check_win() def check_adjusts(self, sender): td_keys = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] for key in td_keys: if self.incr_buttons[key] == sender: self.change_td_const(key, '+') if self.decr_buttons[key] == sender: self.change_td_const(key, '-') self.adj_labels[key].setText("Constant %d: %f" % (key[1], self.TD_CONSTS[key])) def change_td_const(self, key, sign): if sign == '+': self.TD_CONSTS[key] += INCREMENT_AMOUNT elif sign == '-': self.TD_CONSTS[key] -= INCREMENT_AMOUNT def check_win(self): self.depth_label.setHTML("""AI will search to a <a href="#depth_explanation">depth</a> of """ + str(self.depthLimit) +".") self.check_adjusts(None) human_score = self.state.score[str(self.min_player)] ai_score = self.state.score[str(self.max_player)] self.score_label.setText("CURRENT SCORE: Human(%d): %d | AI(%d): %d" % (self.min_player, human_score, self.max_player, ai_score)) if is_over(self.state): if human_score > ai_score: msg = "Congratulations, you won! To increase the difficulty, increase the search depth." elif human_score < ai_score: msg = "You lost! Better luck next time." elif human_score == ai_score: msg = "Game ends in a tie." self.game_over_msg.setHTML("<H3>" + msg + "</H3>") self.game_over = True if self.game_over: self.game_over_msg.setVisible(True) else: self.game_over_msg.setVisible(False) def will_buttons(self, y_board, x_board): # first we determine if the next_piece points to a playable board. board = self.state.boards piece = list(self.state.next_piece) playable = True if is_win(board[piece[0]][piece[1]]) or is_full(board[piece[0]][piece[1]]): playable = False if (not is_win(board[y_board][x_board])) and (not is_full(board[y_board][x_board])): if not playable: return True if playable: return (y_board == piece[0]) and (x_board == piece[1]) return False def state_to_grid(self, prev_x_board=-1, prev_y_board=-1, prev_x_cell=-1, prev_y_cell=-1): board = self.state.boards for y_board in range(3): for x_board in range(3): # for this mini-grid, do i make buttons or dashes? will_make_buttons = self.will_buttons(y_board, x_board) g=Grid() g.resize(3, 3) g.setBorderWidth(2) g.setCellPadding(9) g.setCellSpacing(1) for y_cell in range(3): for x_cell in range(3): if board[y_board][x_board][y_cell][x_cell]['cell'] == 0: if will_make_buttons: if self.min_player == -1: b = Button('Play 1 here.', self) else: b = Button('Play %d here.' % (self.state.next_piece[2]), self) b.point = {'x_cell':x_cell, 'y_cell':y_cell, 'y_board': y_board, 'x_board': x_board} else: b = HTML('-') elif board[y_board][x_board][y_cell][x_cell]['cell'] == 1: if (prev_x_cell == x_cell and prev_y_cell == y_cell and prev_y_board == y_board and prev_x_board == x_board): b = HTML('<p style="color:red">1</p>') else: b = HTML('1') elif board[y_board][x_board][y_cell][x_cell]['cell'] == 2: if (prev_x_cell == x_cell and prev_y_cell == y_cell and prev_y_board == y_board and prev_x_board == x_board): b = HTML('<p style="color:red">2</p>') else: b = HTML('2') g.setWidget(y_cell, x_cell, b) self.add(g) self.g.setWidget(y_board, x_board, g) def grid_to_state(self, point): board = self.state.boards for y_board in range(3): for x_board in range(3): g = self.g.getWidget(y_board, x_board) for y_cell in range(3): for x_cell in range(3): if isinstance(g.getWidget(y_cell, x_cell), Button): assert board[y_board][x_board][y_cell][x_cell]['cell'] == 0 elif (g.getText(y_cell, x_cell) == '1') or (g.getText(y_cell, x_cell) == '2'): if self.state.boards[y_board][x_board][y_cell][x_cell]['cell'] == 0: self.state.boards[y_board][x_board][y_cell][x_cell]['cell'] = int(g.getText(y_cell, x_cell)) piece = self.state.next_piece piece[0] = y_cell piece[1] = x_cell else: assert (g.getText(y_cell, x_cell) == '-') if is_win(self.state.boards[point['y_board']][point['x_board']]): self.state.score[str(self.min_player)] += 1
class IntroPage: DiceInstance = 0 VarTempScore = 0 #Temporary Score Variable VarTotScore = [] #Total Score Variable CountTurn = 1 #Count to display player number in Temporary Score Board def __init__(self): self.DPanel = DockPanel(HorizontalAlignment = HasAlignment.ALIGN_CENTER, Spacing=10) # Creates the Docker Panel Instance self.VPanel = VerticalPanel() # Creates the Vertical Panel Instance self.VPanel1 = VerticalPanel() # Creates the Vertical Panel Instance self.HPanel = HorizontalPanel() # Creates a Horizontal Panel Instance self.HPanel1 = HorizontalPanel()# Creates a Horizontal Panel Instance self.image=Image()#Creates the Image instance to embed the images of dice self.DummyUrl = self.image.getUrl() self.timer = Timer(notify=self.StillImage)#Timer for display of gif animation self.timerRButton = Timer(notify=self.OneAlert)#Timer for controlling states of Roll button #whenever the output of the dice is 1 self.RollButton = Button("Roll", getattr(self, "RollButtonPressed")) #Initially Disabled self.RollButton.setEnabled(False) self.BankButton = Button("Bank", getattr(self, "BankButtonPressed")) #Initially Disabled self.BankButton.setEnabled(False) #The start button controls both the number players as well the winning score self.StartButton = Button("Start", getattr(self, "StartButtonPressed")) #Intially Enabled self.StartButton.setEnabled(True) self.PlayerNum = TextBox() #Enter the Number of Players self.WinScore = TextBox() #Enter the Target Score self.PlayerNum.setText("0") self.WinScore.setText("0") # self.OK = Button("OK", getattr(self, "okButtonPressed")) self.NameScore = FlexTable() #main score board self.NameScore.setStyleName("NameScore") self.TempBoard = FlexTable() #Temporary score board self.TempBoard.setStyleName("TempBoard") self.TxtInstructions = HTML() def StartButtonPressed(self): self.CountTurn = 1 if int(self.PlayerNum.getText()) >= 2 and int(self.PlayerNum.getText()) <= 6 and int(self.WinScore.getText()) >= 10 and int(self.WinScore.getText()) <= 100: self.DPanel.remove(self.TxtInstructions, DockPanel.CENTER) self.BankButton.setVisible(True) self.RollButton.setVisible(True) # self.image.setVisible(True) self.TempBoard.setVisible(True) self.NameScore.setVisible(True) self.image = Image( self.DummyUrl + "images/0.png") self.image.setSize("200px", "300px") self.DPanel.add(self.image, DockPanel.CENTER) RootPanel().add(self.DPanel) self.StartButton.setEnabled(False) self.PlayerNum.setEnabled(False) self.WinScore.setEnabled(False) self.RollButton.setEnabled(True) self.TempBoard.setText(1,0,"Player"+str(1)) self.TempBoard.setText(1, 1, "0") self.NameScore.getRowFormatter().addStyleName(self.CountTurn,"Rows") else: Window.alert("Please Enter Correct Parameters " ) #Command for alert window return 0 VarPlayer = ["Player" + str(i) for i in xrange(1,int(self.PlayerNum.getText())+1)] i = 0 while i < int(self.PlayerNum.getText()): self.NameScore.setText(i+1, 0, VarPlayer[i]) self.NameScore.setText(i+1, 1, "0") self.VarTotScore.append(0) #m*1 vector of zeros indicating the initial scores i += 1 def OneAlert(self): AlrtTxt = " Sorry, your turn is over" Window.alert(AlrtTxt) self.timerRButton.cancel() self.RollButton.setEnabled(True) def StillImage(self): self.DPanel.remove(self.image, DockPanel.CENTER) self.image = Image( self.DummyUrl + "images/" +str(self.DiceInstance)+".png") self.image.setSize("300px", "300px") self.DPanel.add(self.image, DockPanel.CENTER) self.DPanel.setCellHeight(self.image, "300px") self.DPanel.setCellWidth(self.image, "600px") RootPanel().add(self.DPanel) self.timer.cancel() if self.DiceInstance != 1: self.TempBoard.setText(1, 1, self.DiceInstance + int(self.TempBoard.getText(1, 1))) self.BankButton.setEnabled(True) self.RollButton.setEnabled(True) else: self.NameScore.getRowFormatter().removeStyleName(self.CountTurn,"Rows") self.RollButton.setEnabled(False) self.timerRButton.schedule(1500) self.CountTurn += 1 if self.CountTurn % int(self.PlayerNum.getText()) == 1: self.CountTurn = 1 self.TempBoard.setText(1,0,"Player"+str(self.CountTurn)) self.TempBoard.setText(1, 1, "0") self.NameScore.getRowFormatter().addStyleName(self.CountTurn,"Rows"); else: self.TempBoard.setText(1,0,"Player"+str(self.CountTurn)) self.TempBoard.setText(1, 1, "0") self.NameScore.getRowFormatter().addStyleName(self.CountTurn,"Rows"); def RollButtonPressed(self): self.DiceInstance = random.randint(1, 6) # value turned after rolling the dice self.DPanel.remove(self.image, DockPanel.CENTER) self.image = Image("http://www.animatedimages.org/data/media/710/animated-dice-image-0064.gif") self.image.setSize("100px", "200px") self.DPanel.add(self.image, DockPanel.CENTER) self.DPanel.setCellHeight(self.image, "300px") self.DPanel.setCellWidth(self.image, "600px") RootPanel().add(self.DPanel) self.BankButton.setEnabled(False) self.RollButton.setEnabled(False) self.timer.schedule(3000) def BankButtonPressed(self): self.BankButton.setEnabled(False) self.NameScore.setText(self.CountTurn, 1, int(self.NameScore.getText(self.CountTurn, 1)) + int(self.TempBoard.getText(1,1))) if int(self.NameScore.getText(self.CountTurn, 1)) >= int(self.WinScore.getText()): AlrtTxt = "Congratulation!!! Player"+ str(self.CountTurn) + " wins !!!!" Window.alert(AlrtTxt) self.DPanel.remove(self.image, DockPanel.CENTER) self.DPanel.add(self.TxtInstructions, DockPanel.CENTER) self.BankButton.setVisible(False) self.RollButton.setVisible(False) # self.image.setVisible(False) self.TempBoard.setVisible(False) self.NameScore.setVisible(False) i = int(self.PlayerNum.getText()) while i > 0: self.NameScore. removeRow(i) i -= 1 self.TempBoard.setText(1,0,"X") self.TempBoard.setText(1, 1, "0") self.StartButton.setEnabled(True) # self.OK.setEnabled(True) self.PlayerNum.setEnabled(True) self.WinScore.setEnabled(True) self.RollButton.setEnabled(False) self.BankButton.setEnabled(False) self.NameScore.getRowFormatter().removeStyleName(self.CountTurn,"Rows"); self.DPanel.remove(self.image, DockPanel.CENTER) self.image = Image( self.DummyUrl + "images/0.png") self.image.setSize("200px", "300px") self.DPanel.add(self.image, DockPanel.CENTER) self.DPanel.setCellHeight(self.image, "200px") self.DPanel.setCellWidth(self.image, "400px") RootPanel().add(self.DPanel) else: self.NameScore.getRowFormatter().removeStyleName(self.CountTurn,"Rows"); self.CountTurn += 1 if self.CountTurn % int(self.PlayerNum.getText()) == 1: self.CountTurn = 1 self.TempBoard.setText(1,0,"Player"+str(self.CountTurn)) self.TempBoard.setText(1, 1, "0") self.NameScore.getRowFormatter().addStyleName(self.CountTurn,"Rows"); else: self.TempBoard.setText(1,0,"Player"+str(self.CountTurn)) self.TempBoard.setText(1, 1, "0") self.NameScore.getRowFormatter().addStyleName(self.CountTurn,"Rows"); def OnGameLoad(self): self.NameScore.setText(0, 0, "Player ID") self.NameScore.setText(0, 1, "Score") self.NameScore.setCellSpacing(10) self.NameScore.setCellPadding(10) self.NameScore.setBorderWidth(2) self.NameScore.setVisible(False) self.TempBoard.setText(0, 0, "Player's Turn") self.TempBoard.setText(0, 1, "Temporary Score") self.TempBoard.setText(1, 0, "X") self.TempBoard.setText(1, 1, "0") self.TempBoard.setCellSpacing(10) self.TempBoard.setCellPadding(10) self.TempBoard.setBorderWidth(2) self.TempBoard.setVisible(False) #Adding StartButton to Dock panel self.DPanel.add(self.StartButton, DockPanel.EAST) self.DPanel.setCellHeight(self.StartButton, "200px") self.DPanel.setCellWidth(self.StartButton, "20px") Txt = HTML("<center><b>Enter Number of Players (between 2 & 6)</b><center>")#Adding playernumber and winscore textbox to Horizontal Panel Txt1 = HTML("<left><b>Enter Target Score (between 10 & 100)</b><left>") self.HPanel1.add(Txt) self.HPanel1.add(self.PlayerNum) self.HPanel1.add(Txt1) self.HPanel1.add(self.WinScore) self.HPanel1.add(self.StartButton) self.HPanel1.setSpacing(20) #Adding Horizontal panel containing playernumber and winscore textbox to Dock Panel self.DPanel.add(self.HPanel1, DockPanel.NORTH) self.DPanel.setCellHeight(self.HPanel1, "30px") self.DPanel.setCellWidth(self.HPanel1, "2000px") self.TxtInstructions = HTML("<b><u><center>Instructions</center></u><ul><li>Pig is game for 2 to 6 Players.</li><li>Players take turns rolling a dice as many times as they like. </li><li>If a roll is 2, 3, 4, 5 or 6, the player adds that many points to their score for the turn. </li><li>A player may choose to end their turn at any time and 'bank' their points.</li><li>If a player rolls a 1, they lose all their unbanked points and their turn is over.</li><li>The first player to score the target or more wins.</li></ul></b>") self.TxtInstructions.setStyleName("TxtInstructions") self.DPanel.add(self.TxtInstructions, DockPanel.CENTER) self.DPanel.add(self.NameScore, DockPanel.WEST) #Adding main scoreboard to Dock Panel self.DPanel.setCellHeight(self.NameScore, "300px") self.DPanel.setCellWidth(self.NameScore, "100px") self.DPanel.setSpacing(10) self.DPanel.setPadding(2) #Adding Tempboard and BankButton to Horizontal Panel self.HPanel.add(self.TempBoard) #Adding BankButton and RollButton to vertical panel self.VPanel.add(self.RollButton) self.RollButton.setVisible(False) self.VPanel.add(self.BankButton) self.BankButton.setVisible(False) self.VPanel.setSpacing(10) #Adding Vertical panel containing BankButton and RollButton to Horizontal Panel self.HPanel.add(self.VPanel) self.HPanel.setSpacing(40) #Adding Horizontal panel containing Tempboard and vertical panel containing BankButton and RollButton to Dock Panel self.DPanel.add(self.HPanel, DockPanel.SOUTH) self.DPanel.setCellHeight(self.HPanel, "20px") self.DPanel.setCellWidth(self.HPanel, "2000px") RootPanel().add(self.DPanel)
class LatBuilderWeb: def setStyleSheet(self, sheet): e = DOM.createElement('link') e.setAttribute('rel', 'stylesheet') e.setAttribute('type', 'text/css') e.setAttribute('href', sheet) html = Window.getDocumentRoot().parentElement head = html.getElementsByTagName('head').item(0) head.appendChild(e) def includeMathJax(self, config): html = Window.getDocumentRoot().parentElement head = html.getElementsByTagName('head').item(0) e = DOM.createElement('script') e.setAttribute('type', 'text/javascript') e.setAttribute( 'src', 'http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=' + config) head.appendChild(e) e = DOM.createElement('script') e.setAttribute('type', 'text/javascript') e.textContent = 'function Typeset() { MathJax.Hub.Queue(["Typeset",MathJax.Hub]); }' head.appendChild(e) def onModuleLoad(self): self.current_request = None Window.setTitle("Lattice Builder Web Interface") self.setStyleSheet("./LatBuilderWeb.css") self.includeMathJax('TeX-AMS-MML_HTMLorMML') self.TEXT_WAITING = "Lattice Builder is working..." self.TEXT_ERROR = "Server Error" self.FIGURES_OF_MERIT = [ # (key, name) ('{cs}P2', 'P2'), ('{cs}P4', 'P4'), ('{cs}P6', 'P6'), ('{cs}R{alpha}', 'R_alpha'), ('spectral', 'spectral'), ] self.CONSTRUCTION_METHODS = [ ('explicit:{genvec}', "Explicit (Evaluation)", "Evaluates the figure of merit for a given generating vector.<br/>" "<strong>Please specify the generating vector in the Lattice " "Properties panel above.</strong>"), ('exhaustive', "Exhaustive", "Examines all generating vectors and retains the best one."), ('random:{samples}', "Random", "Examines a number of randomly selected generating vectors and " "retains the best one."), ('Korobov', "Korobov", "Examines all generating vectors of the form (1, a, a^2 mod n, " "..., a^s mod n) and retains the best one."), ('random-Korobov:{samples}', "Random Korobov", "Examines a number of randomly selected generating vectors of " "the form (1, a, a^2 mod n, ..., a^s mod n) and retains the " "best one."), ('CBC', "Component-by-Component", "Examines all possible values of the components of the " "generating vector and selects the best ones, one coordinate " "at a time."), ('random-CBC:{samples}', "Random Component-by-Component", "Examines a number of randomly selected values of the " "components of the generating vector and selects the best " "ones, one coordinate at a time."), ('fast-CBC', "Fast Component-by-Component", "Examines all possible values of the components of the " "generating vector and selects the best ones, one coordinate " "at a time. Computation is accelerated by using fast " "Fourier transforms."), ] self.COMBINER_TYPES = [ ('level:max', 'highest level'), ('sum', 'weighted sum'), ('max', 'maximum weighted value'), ] self.NORMALIZATION_TYPES = [ ('norm:P{alpha}-SL10', 'SL10 P-alpha'), ('norm:P{alpha}-DPW08', 'DPW08 P-alpha'), ] captionstyle = { 'Width': '10em', 'HorizontalAlignment': 'right', } self.remote = LatBuilderService() WeightValuesArray.REMOTE = self.remote main_panel = VerticalPanel(Spacing=30) # information info = """<h2>Lattice Builder Web Interface</h2> <p>This Web interface allows <a href="https://github.com/mungerd/latbuilder#readme">Lattice Builder</a> users to call the executable program without having to construct the command line explicitly. </p> <p>Enter the construction parameters below, and press the <em>Search for Good Lattices</em> button. The results will show at the bottom. </p>""" main_panel.add(HTML(info)) self.version_label = HTML() main_panel.add(self.version_label) self.remote.backend_version(self) params_panel = VerticalPanel(Spacing=15) main_panel.add(params_panel) # lattice type and size and dimension lat_panel = VerticalPanel() params_panel.add(CaptionPanel("Lattice Properties", lat_panel)) lat_panel.add( HTML( r'\[ P_n = \left\{ (i \boldsymbol a \bmod n) / n \::\: i = 0, \dots, n \right\} \qquad (\boldsymbol a \in \mathbb Z^s) \]', StyleName='DisplayMath')) self.size = TextBox(Text="2^10") self.size.addChangeListener(self) self.embedded = CheckBox("embedded") self.embedded.addClickListener(self) panel = HorizontalPanel(Spacing=8) panel.add(HTML(r"Size (\(n\)): ", StyleName="CaptionLabel")) panel.add(self.size) panel.add(self.embedded) lat_panel.add(panel) self.dimension = TextBox(Text="3") self.dimension.addChangeListener(self) panel = HorizontalPanel(Spacing=8) panel.add(HTML(r"Dimension (\(s\)): ", StyleName="CaptionLabel")) panel.add(self.dimension) lat_panel.add(panel) self.generating_vector = GeneratingVector(self.size) self.generating_vector.panel.setVisible(False) lat_panel.add(self.generating_vector.panel) # figure of merit merit_panel = VerticalPanel() params_panel.add(CaptionPanel("Figure of Merit", merit_panel)) merit_panel.add( HTML( r"\[ \left[ \mathcal D_q(P_n) \right]^q = " r"\sum_{\emptyset \neq u \subseteq \{1,\dots,s\}}" r"\gamma_u^q \, \left[\mathcal D_u(P_n)\right]^q" r"\qquad (q > 0) \]", StyleName='DisplayMath')) self.norm_type = TextBox(Text="2") self.norm_type.addChangeListener(self) panel = HorizontalPanel(Spacing=8) panel.add( HTML(r"Norm type (\(q\) or <b>inf</b>): ", StyleName="CaptionLabel")) panel.add(self.norm_type) merit_panel.add(panel) self.merit = ListBox() self.merit.addChangeListener(self) for key, name in self.FIGURES_OF_MERIT: self.merit.addItem(name) self.merit_cs = CheckBox("Use coordinate-symmetric implementation", Checked=True) panel = HorizontalPanel(Spacing=8) panel.add(HTML("Figure of merit: ", StyleName="CaptionLabel")) panel.add(self.merit) panel.add(self.merit_cs) merit_panel.add(panel) self.merit_alpha_panel = HorizontalPanel(Spacing=8) self.merit_alpha = TextBox(Text="2") self.merit_alpha_panel.add( HTML("Value of alpha: ", StyleName="CaptionLabel")) self.merit_alpha_panel.add(self.merit_alpha) merit_panel.add(self.merit_alpha_panel) # filters and combiner multilevel_panel = VerticalPanel(Spacing=8) self.multilevel_panel = CaptionPanel("Multilevel Filters and Combiner", multilevel_panel, Visible=False) params_panel.add(self.multilevel_panel) self.ml_normalization_enable = CheckBox("Normalization") self.ml_normalization_enable.addClickListener(self) multilevel_panel.add(self.ml_normalization_enable) self.ml_normalization_panel = VerticalPanel(Spacing=4, Visible=False, StyleName='SubPanel') multilevel_panel.add(self.ml_normalization_panel) panel = HorizontalPanel(Spacing=8) panel.add(HTML("Normalization type: ", StyleName="CaptionLabel")) self.ml_normalization_type = ListBox() for key, name in self.NORMALIZATION_TYPES: self.ml_normalization_type.addItem(name, value=key) panel.add(self.ml_normalization_type) self.ml_normalization_panel.add(panel) panel = HorizontalPanel(Spacing=8) panel.add(HTML("Minimum level: ", StyleName="CaptionLabel")) self.ml_min_level = TextBox(Text="1") panel.add(self.ml_min_level) self.ml_normalization_panel.add(panel) panel = HorizontalPanel(Spacing=8) panel.add(HTML("Maximum level: ", StyleName="CaptionLabel")) self.ml_max_level = TextBox(Text="1") panel.add(self.ml_max_level) self.ml_normalization_panel.add(panel) self.ml_lowpass_enable = CheckBox("Low-pass filter") self.ml_lowpass_enable.addClickListener(self) multilevel_panel.add(self.ml_lowpass_enable) self.ml_lowpass_panel = VerticalPanel(Spacing=4, Visible=False, StyleName='SubPanel') multilevel_panel.add(self.ml_lowpass_panel) self.ml_lowpass = TextBox(Text="1.0") panel = HorizontalPanel(Spacing=8) panel.add(HTML("Low-pass threshold: ", StyleName="CaptionLabel")) panel.add(self.ml_lowpass) self.ml_lowpass_panel.add(panel) self.combiner_type = ListBox() for key, name in self.COMBINER_TYPES: self.combiner_type.addItem(name, value=key) panel = HorizontalPanel(Spacing=8) panel.add(HTML("Combiner: ", StyleName="CaptionLabel")) panel.add(self.combiner_type) multilevel_panel.add(panel) # weights self.weights = CompoundWeights() weights_panel = VerticalPanel() params_panel.add(CaptionPanel("Weights", weights_panel)) weights_panel.add( HTML(r"\[ \gamma_u^p \qquad (u \subseteq \{1, \dots, s\}) \]", StyleName='DisplayMath')) self.weights_power = TextBox(Text="2") panel = HorizontalPanel(Spacing=8) panel.add(HTML(r"Weights power (\(p\)): ", StyleName="CaptionLabel")) panel.add(self.weights_power) weights_panel.add(panel) weights_panel.add(self.weights.panel) self.weights.add_weights(ProductWeights) # construction method cons_panel = VerticalPanel() params_panel.add(CaptionPanel("Construction Method", cons_panel)) self.construction = ListBox() self.construction.addChangeListener(self) for key, name, desc in self.CONSTRUCTION_METHODS: self.construction.addItem(name, value=key) self.construction_desc = HTML() panel = HorizontalPanel(Spacing=8) panel.add(self.construction) panel.add(self.construction_desc) cons_panel.add(panel) self.construction_samples_panel = HorizontalPanel(Spacing=8) self.construction_samples = TextBox(Text="30") self.construction_samples_panel.add( HTML("Random samples: ", StyleName="CaptionLabel")) self.construction_samples_panel.add(self.construction_samples) cons_panel.add(self.construction_samples_panel) # execute button panel = VerticalPanel(Spacing=8, Width="100%", HorizontalAlignment='center') main_panel.add(panel) button_panel = HorizontalPanel() panel.add(button_panel) self.button_search = Button("Search", self) button_panel.add(self.button_search) self.button_abort = Button("Abort", self, Visible=False) button_panel.add(self.button_abort) self.status = Label() panel.add(self.status) # results results_panel = VerticalPanel() self.results_panel = CaptionPanel("Results", results_panel, Visible=False) main_panel.add(self.results_panel) self.results_size = Label() panel = HorizontalPanel(Spacing=8) panel.add(HTML("Lattice size: ", StyleName="ResultsCaptionLabel")) panel.add(self.results_size) results_panel.add(panel) self.results_gen = Label() panel = HorizontalPanel(Spacing=8) panel.add(HTML("Generating vector: ", StyleName="ResultsCaptionLabel")) panel.add(self.results_gen) results_panel.add(panel) self.results_merit = Label() panel = HorizontalPanel(Spacing=8) panel.add(HTML("Merit value: ", StyleName="ResultsCaptionLabel")) panel.add(self.results_merit) results_panel.add(panel) self.results_cpu_time = Label() panel = HorizontalPanel(Spacing=8) panel.add(HTML("CPU time: ", StyleName="ResultsCaptionLabel")) panel.add(self.results_cpu_time) results_panel.add(panel) self.results_cmd = Label(StyleName='Command', Visible=False) panel = HorizontalPanel(Spacing=8) self.results_cmd_link = Hyperlink("Command line: ", StyleName="ResultsCaptionLabel") self.results_cmd_link.addClickListener(self) panel.add(self.results_cmd_link) panel.add(self.results_cmd) results_panel.add(panel) # update selections self.construction.selectValue('CBC') self.onChange(self.size) self.onChange(self.construction) self.onChange(self.merit) self.onChange(self.dimension) self.onClick(self.embedded) self.onChange(self.ml_normalization_enable) self.onChange(self.ml_lowpass_enable) RootPanel().add(main_panel) def onChange(self, sender): if sender == self.construction: key, name, desc = \ self.CONSTRUCTION_METHODS[self.construction.getSelectedIndex()] self.construction_desc.setHTML(desc) self.construction_samples_panel.setVisible('{samples}' in key) if key.startswith('explicit'): self.generating_vector.panel.setVisible(True) self.button_search.setText("Evaluate Figure of Merit") else: self.generating_vector.panel.setVisible(False) self.button_search.setText("Search for Good Lattices") elif sender == self.merit: key, name = \ self.FIGURES_OF_MERIT[self.merit.getSelectedIndex()] self.merit_alpha_panel.setVisible('{alpha}' in key) self.merit_cs.setVisible('{cs}' in key) elif sender == self.size: max_level = LatSize(self.size.getText()).max_level if int(self.ml_min_level.getText()) > max_level: self.ml_min_level.setText(max_level) self.ml_max_level.setText(max_level) elif sender == self.dimension: # resize weights dimension = int(self.dimension.getText()) self.generating_vector.dimension = dimension self.weights.dimension = dimension elif sender == self.norm_type: q = self.norm_type.getText().strip() self.merit_cs.setVisible(q == '2') if q == 'inf': self.weights_power.setText('1') else: self.weights_power.setText(q) def onClick(self, sender): if sender == self.embedded: self.multilevel_panel.setVisible(self.embedded.getChecked()) elif sender == self.ml_normalization_enable: self.ml_normalization_panel.setVisible( self.ml_normalization_enable.getChecked()) elif sender == self.ml_lowpass_enable: self.ml_lowpass_panel.setVisible( self.ml_lowpass_enable.getChecked()) elif sender == self.results_cmd_link: self.results_cmd.setVisible(not self.results_cmd.getVisible()) elif sender == self.button_search: self.results_panel.setVisible(False) self.button_search.setVisible(False) self.button_abort.setVisible(True) lattype = self.embedded.getChecked() and 'embedded' or 'ordinary' size = self.size.getText() dimension = self.dimension.getText() norm_type = self.norm_type.getText() merit, merit_name = \ self.FIGURES_OF_MERIT[self.merit.getSelectedIndex()] alpha = self.merit_alpha.getText() cs = norm_type == 2 and self.merit_cs.getChecked() and 'CS:' or '' weights_power = self.weights_power.getText() weights = [w.as_arg() for w in self.weights.weights] construction, construction_name, desc = \ self.CONSTRUCTION_METHODS[self.construction.getSelectedIndex()] samples = self.construction_samples.getText() genvec = ','.join(self.generating_vector.values) mlfilters = [] combiner_type = None if self.embedded.getChecked(): if self.ml_normalization_enable.getChecked(): ml_normalization_type, ml_normalization_name = \ self.NORMALIZATION_TYPES[self.ml_normalization_type.getSelectedIndex()] ml_normalization_type += ':even:{},{}'.format( self.ml_min_level.getText(), self.ml_max_level.getText()) mlfilters.append(ml_normalization_type.format(alpha=alpha)) if self.ml_lowpass_enable.getChecked(): mlfilters.append('low-pass:{}'.format( self.ml_lowpass.getText())) combiner_type, combiner_name = \ self.COMBINER_TYPES[self.combiner_type.getSelectedIndex()] self.status.setText(self.TEXT_WAITING) self.current_request = self.remote.latbuilder_exec( lattype, size, dimension, norm_type, merit.format(alpha=alpha, cs=cs), construction.format(samples=samples, genvec=genvec), weights, weights_power, None, mlfilters, combiner_type, self) elif sender == self.button_abort: # Need to patch JSONService.sendRequest(): # # return HTTPRequest().asyncPost(self.url, msg_data, # JSONResponseTextHandler(request_info) # False, self.content_type, # self.headers) if self.current_request: self.current_request.abort() self.current_request = None self.button_abort.setVisible(False) self.button_search.setVisible(True) elif sender == self.product_weights_expr_link: self.showDialog(self._product_weights_expr_dialog) elif sender == self.order_weights_expr_link: self.showDialog(self._order_weights_expr_dialog) def onRemoteResponse(self, response, request_info): try: if request_info.method == 'latbuilder_exec': self.button_search.setVisible(True) self.button_abort.setVisible(False) cmd, points, gen, merit, seconds = eval(response) self.results_size.setText(points) self.results_gen.setText(', '.join(gen)) self.results_merit.setText(merit) self.results_cpu_time.setText(format_time(seconds=seconds)) self.results_cmd.setText(cmd) self.results_panel.setVisible(True) self.status.setText("") elif request_info.method == 'backend_version': version = response self.version_label.setHTML( "<b>Backend:</b> {}".format(version)) except: self.status.setText(response.replace('\n', ' | ')) def onRemoteError(self, code, errobj, request_info): if request_info.method == 'latbuilder_exec': self.button_search.setVisible(True) self.button_abort.setVisible(False) message = errobj['message'] if code != 0: self.status.setText("HTTP error %d: %s" % (code, message['name'])) else: code = errobj['code'] if code == -32603: self.status.setText("Aborted.") else: self.status.setText("JSONRPC Error %s: %s" % (code, message))
class GridWidget(AbsolutePanel): def __init__(self): AbsolutePanel.__init__(self) StyleSheetCssText(margins) # initialize css... header = """<div><H2 align="center">Welcome to Unbeatable Tic-Tac-Toe!</H2><br>My <a href="https://github.com/chetweger/min-max-games/blob/master/ttt/ttt.py">implementation</a> uses the min-max search algorithm with alpha beta pruning and a transposition table!</div>""" header = HTML(header, StyleName='margins_both') self.add(header) self.ai_first = Button("AI first.", self, StyleName='margins_left') self.add(self.ai_first) self.new_game = Button("New game", self, StyleName='margins_left') self.add(self.new_game) self.g=Grid(StyleName='margins_left') self.g.resize(3, 3) self.g.setBorderWidth(2) self.g.setCellPadding(4) self.g.setCellSpacing(1) self.init() self.add(self.g) self.state = State() self.game_resolution=Label("", StyleName='margins_left') self.add(self.game_resolution) def start_new_game(self): self.state = State() self.game_over = False self.ai_first.setVisible(True) self.state_to_grid(self.state) def onClick(self, sender): if sender == self.ai_first: print 'player is ', self.state.player self.state.max_v = 1 self.state.min_v = 2 self.ai_first.setVisible(False) print 'button ai_first exists', hasattr(self, 'ai_first') self.state.print_me() next_state = ab(self.state) self.state = next_state self.state_to_grid(next_state) print '[after]player is ', self.state.player elif sender == self.new_game: self.start_new_game() else: print 'player is ', self.state.player ''' self.g.setText(0, 1, 'wassup') self.g.setText(p['x'], p['y'], str(self.state.min_v)) ''' if self.ai_first.isVisible(): print 'Setting state.max_v' self.state.max_v = 2 self.state.min_v = 1 self.ai_first.setVisible(False) p = sender.point self.g.setText(p['y'], p['x'], str(self.state.player)) self.state = self.grid_to_state() self.check_for_tie() # end 1 if is_win(self.state): self.state_to_grid(self.state, game_over=True, over_message='You won! This should not happen. This is a bug. Please email [email protected] describing the conditions of the game.') self.state.player = next_player(self.state.player) self.state.print_me() next_state = ab(self.state) self.state = next_state self.state_to_grid(next_state) self.check_for_tie() # end 1 if is_win(self.state): self.state_to_grid(self.state, game_over=True, over_message='You lost! Better luck next time.') def check_for_tie(self): if is_over(self.state): self.state_to_grid(self.state, game_over=True, over_message='The game is a tie.') def state_to_grid(self, state, game_over=False, over_message=''): if over_message: self.game_resolution.setText(over_message) self.game_resolution.setVisible(True) else: self.game_resolution.setVisible(False) board = state.board for y in range(3): for x in range(3): if board[y][x] == 0: if not game_over: b = Button('Press', self) b.point = {'x':x, 'y':y} self.g.setWidget(y, x, b) else: self.g.setText(y, x, '-') elif board[y][x] == '1': self.g.setText(y, x, '1') elif board[y][x] == '2': self.g.setText(y, x, '2') else: print 'state_to_grid exception' #assert False def grid_to_state(self): next_state = State() for y in range(3): for x in range(3): if isinstance(self.g.getWidget(y, x), Button): print y, x next_state.board[y][x] = 0 elif self.g.getText(y, x) == '1' or self.g.getText(y, x) == '2': next_state.board[y][x] = int(self.g.getText(y,x)) else: print 'grid_to_state exception' #assert False next_state.min_v = self.state.min_v next_state.max_v = self.state.max_v next_state.player = self.state.player return next_state def init(self): for y in range(3): for x in range(3): b = Button('Press', self) b.point = {'x':x, 'y':y} self.g.setWidget(y, x, b)