def make_panel(self): message = Label( 'The configuration has been changed.\n' 'You must apply the changes in order for them to take effect.') DOM.setStyleAttribute(message.getElement(), "whiteSpace", 'pre') msgbox = Grid(1, 2, StyleName='changes') msgbox.setWidget(0, 0, Image('icons/exclam.png')) msgbox.setWidget(0, 1, message) msgbox.getCellFormatter().setStyleName(0, 0, 'changes-image') msgbox.getCellFormatter().setStyleName(0, 1, 'changes-text') button = Button('apply changes') button.addClickListener(self.apply_clicked) self.changes = VerticalPanel() self.changes.setHorizontalAlignment('right') self.changes.setVisible(False) self.changes.add(msgbox) self.changes.add(button) panel = VerticalPanel() panel.setSpacing(10) panel.add(self.table) panel.add(self.status) panel.add(self.changes) return panel
class TickeryTab(VerticalPanel): process = None # Define in subclass. def __init__(self, topPanel, **kwargs): VerticalPanel.__init__(self, HorizontalAlignment=HasAlignment.ALIGN_LEFT, StyleName='tickery-tab', **kwargs) self.topPanel = topPanel # don't add this yet! self.topGrid = Grid(1, 2, StyleName='tickery-tab-top-grid', HorizontalAlignment=HasAlignment.ALIGN_LEFT) self.add(self.topGrid) self.autoActivate = False def addTopPanel(self): parent = self.topPanel.getParent() if parent: parent.remove(self.topPanel) self.topGrid.setWidget(0, 0, self.topPanel) formatter = self.topGrid.getCellFormatter() formatter.setAlignment(0, 0, 'left', 'top') formatter.setAlignment(0, 1, 'left', 'top') formatter.setWidth(0, 1, '100%') def onTimer(self, timerid): self.setInputFocus() if self.autoActivate: self.autoActivate = False self.process()
class GridWidget(AbsolutePanel): def __init__(self): AbsolutePanel.__init__(self) self.page=0 self.min_page=1 self.max_page=10 self.addb=Button("Next >", self) self.subb=Button("< Prev", self) self.clearb=Button("Clear", self) self.g=Grid() self.g.resize(5, 5) self.g.setWidget(0, 0, HTML("<b>Grid Test</b>")) self.g.setBorderWidth(2) self.g.setCellPadding(4) self.g.setCellSpacing(1) self.updatePageDisplay() self.add(self.subb) self.add(self.addb) self.add(self.clearb) self.add(self.g) def onClick(self, sender): if sender == self.clearb: print "clear" self.g.clear() return elif sender==self.addb: self.page+=1 elif sender==self.subb: self.page-=1 self.updatePageDisplay() def updatePageDisplay(self): if self.page<self.min_page: self.page=self.min_page elif self.page>self.max_page: self.page=self.max_page total_pages=(self.max_page-self.min_page) + 1 self.g.setHTML(0, 4, "<b>page %d of %d</b>" % (self.page, total_pages)) if self.page>=self.max_page: self.addb.setEnabled(False) else: self.addb.setEnabled(True) if self.page<=self.min_page: self.subb.setEnabled(False) else: self.subb.setEnabled(True) for y in range(1, 5): for x in range(5): self.g.setText(y, x, "%d (%d,%d)" % (self.page, x, y))
class AccountListSink(VerticalPanel): def __init__(self, hendler = None): VerticalPanel.__init__(self, #HorizontalAlignment=HasAlignment.ALIGN_CENTER, #VerticalAlignment=HasAlignment.ALIGN_MIDDLE, Width="100%", #Height="100%", Spacing=5) self.remote = DataService(['getaccounts']) self.grid = Grid(1, 3, BorderWidth=1, CellPadding=4, CellSpacing=1, StyleName="grid") self.grid.setText(0, 0, u"Number") self.grid.setText(0, 1, u"Type") self.grid.setText(0, 2, u"Balance") formatter = self.grid.getRowFormatter() formatter.setStyleName(0, "grid-header") self.add(Label(u"Accounts")) self.add(self.grid) def updateGrid(self, accounts): rows = len(accounts) if rows > 0: self.grid.resize(rows+1, 3) for row in range(rows): link = PseudoLink(accounts[row]['number'], self.onClick, ID=accounts[row]['number']) self.grid.setWidget(row+1, 0, link) self.grid.setText(row+1, 1, accounts[row]['type']) self.grid.setText(row+1, 2, accounts[row]['balance']) def onShow(self): self.remote.getaccounts(self) def onClick(self, sender): Window.alert(sender.getID()) def onRemoteResponse(self, response, request_info): ''' Called when a response is received from a RPC. ''' if request_info.method == 'getaccounts': #TODO self.updateGrid(response) else: Window.alert('Unrecognized JSONRPC method.') def onRemoteError(self, code, message, request_info): Window.alert(message)
def start_game(self): dim = self.level grid = Grid(dim, dim) grid.setStyleName("grid") for i in range(dim): for j in range(dim): gc = GridCell(i, j) grid.setWidget(i, j, gc) self.add(grid)
def start_game(self): dim = self.level grid = Grid(dim,dim) grid.setStyleName("grid") for i in range(dim): for j in range(dim): gc = GridCell(i,j) grid.setWidget(i,j,gc) self.add(grid)
class RightPanel(DockPanel): def __init__(self): DockPanel.__init__(self) self.grids = {} self.g = Grid() self.g.setCellSpacing("0px") self.g.setCellPadding("8px") self.title = HTML(" ") self.title.setStyleName("rightpanel-title") self.add(self.title, DockPanel.NORTH) self.setCellWidth(self.title, "100%") self.setCellHorizontalAlignment(self.title, HasHorizontalAlignment.ALIGN_LEFT) self.add(self.g, DockPanel.CENTER) def setTitle(self, title): self.title.setHTML(title) def clear_items(self): for i in range(len(self.grids)): g = self.grids[i] if hasattr(g, "clear_items"): g.clear_items() self.grids = {} self.g.resize(0, 0) def setup_panels(self, datasets): self.grids = {} self.data = {} self.names = {} self.loaded = {} size = len(datasets) self.g.resize(size, 1) #for i in range(size): # item = datasets[i] # fname = item[0] # self.grids[i] = RightGrid(fname) # self.g.setWidget(i, 0, self.grids[i]) def add_html(self, html, name, index): self.data[index] = html self.names[index] = name self.grids[index] = HTML(html) self.g.setWidget(index, 0, self.grids[index]) def add_items(self, items, name, index): self.data[index] = items self.names[index] = name self.grids[index] = RightGrid("") self.grids[index].set_items(items) self.g.setWidget(index, 0, self.grids[index])
def start_game(self, level=None): if level is not None: self.level = level dim = self.level grid = Grid(dim,dim) grid.setStyleName("grid") for i in range(dim): for j in range(dim): gc = GridCell(i,j) grid.setWidget(i,j,gc) self.add(grid)
class OddGridWidget(DockPanel): def __init__(self, **kwargs): DockPanel.__init__(self, **kwargs) self.grid = Grid(StyleName="datagrid") self.sp = ScrollPanel(self.grid, Width="100%", Height="100%") self.header = Grid(Height="50px") self.add(self.header, DockPanel.NORTH) self.add(self.sp, DockPanel.CENTER) cf = self.setCellHeight(self.header, "50px") cf = self.setCellHeight(self.sp, "100%") self.sortcol = 0 def setData(self, data): self.data = data self.redraw() def sortfn(self, row1, row2): return cmp(row1[self.sortcol], row2[self.sortcol]) def redraw(self): self.data.sort(self.sortfn) rows = len(self.data) cols = 0 if rows > 0: cols = len(self.data[0]) self.grid.resize(rows, cols) self.header.resize(1, cols) cf = self.grid.getCellFormatter() for (nrow, row) in enumerate(self.data): for (ncol, item) in enumerate(row): self.grid.setHTML(nrow, ncol, str(item)) cf.setWidth(nrow, ncol, "200px") cf = self.header.getCellFormatter() self.sortbuttons = [] for ncol in range(cols): sb = Button("sort col %d" % ncol) sb.addClickListener(self) self.header.setWidget(0, ncol, sb) cf.setWidth(0, ncol, "200px") self.sortbuttons.append(sb) def onClick(self, sender): for (ncol, b) in enumerate(self.sortbuttons): if sender == b: self.sortcol = ncol self.redraw()
def createResultGrid( self, gridName ) : label=HTML('<br><b>'+gridName+'</b>') grid=Grid(17,17) # Create the column and row headers for index in range( 1, grid.getColumnCount() ) : grid.setWidget( 0, index, HTML('Cx%X'%(index-1)) ) for index in range( 1, grid.getRowCount() ) : grid.setWidget( index, 0, HTML('C%Xx'%(index-1)) ) self.mainPanel.add(label) self.mainPanel.add(grid) self.resultLabels[gridName]=label self.resultGrids[gridName]=grid
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 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 __init__(self): # layed out in a grid with odd rows a different color for # visual separation #lucky = Grid(9,10, CellPadding=25, CellSpacing=1, BorderWidth=1) lucky = Grid() lucky.resize(9,10) lucky.setBorderWidth(1) lucky.setCellPadding(25) lucky.setCellSpacing(1) val = 0 for x in range(0,9): for y in range(0,10): val += 1 lucky.setText(x,y,val) grid = Grid(1,3,CellPadding=20,CellSpacing=0) rf = grid.getRowFormatter() rf.setStyleName(0, 'oddrow') # popup timer buttons ptb = PopupTimerButton(1) grid.setWidget(0, 0, CaptionPanel('Start the Lucky Number Countdown', ptb, StyleName='left')) grid.setWidget(0, 1, CaptionPanel('Current Lucky Number',ptb.box)) grid.setWidget(0, 2, lucky) # add it all to the root panel RootPanel().add(grid, lucky)
def __init__(self, listener): VerticalPanel.__init__(self, StyleName = "login") self.listener = listener self.remote = DataService(['login']) form_panel = VerticalPanel(ID = "container", StyleName = "form") self.error_message = Label(StyleName = "error-message") grid = Grid(2, 2, CellPadding=0, CellSpacing=0, StyleName = "form-grid") grid.setWidget(0, 0, Label(JS('gettext("Username:"******"label")) self.tb = TextBox(Name="username") grid.setWidget(0, 1, self.tb) grid.setWidget(1, 0, Label(JS('gettext("Password:"******"label")) self.ptb = PasswordTextBox(Name="password") grid.setWidget(1, 1, self.ptb) form_panel.add(Label(JS('gettext("User Login")'), StyleName = "form-title")) form_panel.add(self.error_message) form_panel.add(grid) button_box = HorizontalPanel(Width="100%") register_button = PseudoLink(JS('gettext("Create an account")'), self.onRegisterButtonClick) submit_button = Button(JS('gettext("Login")'), self.onSubmitButtonClick) button_box.add(register_button) button_box.add(submit_button) button_box.setCellHorizontalAlignment(submit_button, HasAlignment.ALIGN_RIGHT) form_panel.add(button_box) self.add(form_panel)
def __init__(self, topPanel): TickeryTab.__init__(self, topPanel) # Get the query string and wanted tab, if any, from URL args. args = Window.getLocation().getSearchDict() query = args.get('query') wantedTab = args.get('tab') if wantedTab: wantedTab = wantedTab.lower() if query and wantedTab == self.tabName.lower(): query = urllib.unquote_plus(query) self.autoActivate = True else: query = self.defaultQuery self.instructions.setHorizontalAlignment(HasAlignment.ALIGN_LEFT) self.instructions.setStyleName('instructions-popup') self.popup = InstructionBox( self.__class__.__name__, self.instructions) self.popup.setText(self.instructionsTitle) self.db = Button(HELP_TEXT, StyleName='help-button') self.db.addClickListener(self) huhId = HTMLPanel.createUniqueId() help = HTMLPanel('%s <span id="%s"></span>' % (SHORT_INSTRUCTIONS[self.tabName], huhId), StyleName='simple-instructions') help.add(self.db, huhId) self.goButton = go.GoButton(self) self.query = text.TextAreaFocusHighlight(Text=query, VisibleLines=3, StyleName='large-query-area') self.checkResult = HorizontalPanel(Spacing=4) mainGrid = Grid(2, 2, StyleName='tickery-tab-panel', HorizontalAlignment=HasAlignment.ALIGN_LEFT) formatter = mainGrid.getCellFormatter() mainGrid.setWidget(0, 0, help) mainGrid.setWidget(1, 0, self.query) mainGrid.setWidget(1, 1, self.goButton) formatter.setHorizontalAlignment(0, 0, 'left') formatter.setHorizontalAlignment(1, 0, 'left') formatter.setAlignment(1, 1, 'left', 'bottom') self.topGrid.setWidget(0, 1, mainGrid) self.add(self.checkResult) self.results = userlist.UserListPanel(self, topPanel, HorizontalAlignment=HasAlignment.ALIGN_LEFT) self.add(self.results)
def onModuleLoad(self): self.popupsubtraca = PopupSub(id="sub",datasrc="fsubtracao.pjs") self.popupsoma = PopupSoma(id="soma",datasrc="fsoma.pjs") self.popupmultescalar = PopupEscalar(id="escalar",datasrc="fmultescalar.pjs") self.popupmult = PopupProduto(id="mult",datasrc="fmult.pjs") self.popupsoma.iniciado = False; tabpanel = TabPanel() grid = Grid(4,2) imgbtnSoma = Image("images/Soma_Matriz_sum_matrix.png",StyleName="gwt-ImageButton") imgbtnSubtracao = Image("images/subtracao_Matriz_subtract_matrix.png",StyleName="gwt-ImageButton") imgbtnMultiplicacao = Image("images/multiplicacao_Matriz_product_matrix.png",StyleName="gwt-ImageButton") imgbtnMultiplicacaoPorEscalar = Image("images/multiplicacao_por_escalar.png",StyleName="gwt-ImageButton") #eventos imgbtnSoma.addClickListener(self.onSomaButtonClick) imgbtnSubtracao.addClickListener(self.onSubtracaoButtonClick) imgbtnMultiplicacao.addClickListener(self.onMultiplicacaoButtonClick) imgbtnMultiplicacaoPorEscalar.addClickListener(self.onMulPorEscalarButtonClick) contents = VerticalPanel() contents.setSpacing(4) contents.add(HTML('You can place any contents you like in a dialog box.')) grid.setWidget(0,0,imgbtnSoma) grid.setWidget(0,1,imgbtnSubtracao) grid.setWidget(2,0,imgbtnMultiplicacao) grid.setWidget(2,1,imgbtnMultiplicacaoPorEscalar) grid.setStyleName(element) tabpanel.add(HTML("Modulo de introducao a matrizes"),"<h2>Modulo de introducao a Matrizes</h2>", True) tabpanel.add(grid,"<h2> Matrizes </h2>", True) tabpanel.add(HTML("Modulo de introducao a matrizes"),"<h2>Ajuda para usar a ferramenta</h2>", True) tabpanel.setSize("90%"," 70%") tabpanel.selectTab(1) #self.popupsoma.show() RootPanel("conteudo").add(tabpanel)
class CompaniesAppGUI(AbsolutePanel): def __init__(self): AbsolutePanel.__init__(self) self.app = CompaniesApp() self.history = [] self.save = Button("save", self) self.selectDepartment = Button("select", self) self.selectEmployee = Button("select", self) self.edit = Button("edit", self) self.cut = Button("cut", self) self.back = Button("back", self) self.name = TextBox() self.address = TextBox() self.manager = TextBox() self.departments = ListBox(Size=("100%"), VisibleItemCount="5") self.employees = ListBox(Size=("100%"), VisibleItemCount="5") self.total = TextBox() self.errors = VerticalPanel() self.grid = Grid() self.allPanels = VerticalPanel() self.allPanels.add(self.grid) self.allPanels.add(self.errors) self.add(self.allPanels) self.initCompanyGUI() def onClick(self, sender): self.errors.clear() if sender == self.cut: self.current.cut() self.total.setText(self.current.total()) if sender == self.save: if self.current.__class__.__name__ == "Employee": if self.validateEmployee(self.current.id, self.name.getText(), self.address.getText(), self.total.getText()) == True: self.current.save(self.name.getText(), self.address.getText(), float(self.total.getText())) else: if self.validateDepartment(self.current.id, self.name.getText()) == True: self.current.save(self.name.getText()) if sender == self.selectDepartment: if (self.departments.getSelectedIndex() > -1): self.history.append(self.current) self.current = self.app.getDepartment(self.departments.getValue(self.departments.getSelectedIndex())) self.initDepartmentGUI() if sender == self.selectEmployee: if (self.employees.getSelectedIndex() > -1): self.history.append(self.current) self.current = self.app.getEmployee(self.employees.getValue(self.employees.getSelectedIndex())) self.initEmployeeGUI() if sender == self.edit: self.history.append(self.current) self.current = self.current.getManager() self.initEmployeeGUI() if sender == self.back: if len(self.history) > 0: self.current = self.history.pop() if self.current.__class__.__name__ == "Company": self.initCompanyGUI() else: self.initDepartmentGUI() def validateDepartment(self, index, name): valid = True if name == "": self.errors.add(Label("- Enter a valid name, please.")) valid = False for item in self.app.departments: if item.id != index and name == item.name: self.errors.add(Label("- There is already a department with the same name. Enter a valid name, please.")) valid = False return valid def validateEmployee(self, index, name, address, salary): valid = True if name == "": self.errors.add(Label("- Enter a valid name, please.")) valid = False if address == "": self.errors.add(Label("- Enter a valid address, please.")) valid = False if salary == "": self.errors.add(Label("- Enter a valid salary, please.")) valid = False try: float(salary) except ValueError: self.errors.add(Label("- The salary must be a number. Enter a valid salary, please.")) valid = False for item in self.app.employees: if item.id != index and name == item.name and item.address == address: self.errors.add(Label("- There is already an employee with the same name and address combination. Enter a valid name and address, please.")) valid = False return valid def initCompanyGUI(self): self.current = self.app.company self.grid.clear() self.grid.resize(4, 3) # row 1 self.grid.setWidget(0, 0, Label("Name:")) self.grid.setWidget(1, 0, Label("Department:")) self.grid.setWidget(2, 0, Label("Total:")) # row 2 self.grid.setWidget(0, 1, self.name) self.grid.setWidget(1, 1, self.departments) self.grid.setWidget(2, 1, self.total) # row 3 self.grid.setWidget(0, 2, self.save) self.grid.setWidget(1, 2, self.selectDepartment) self.grid.setWidget(2, 2, self.cut) self.name.setText(self.current.name) self.departments.clear() for item in self.current.departments: self.departments.addItem(item.name, item.id) if self.departments.getItemCount() > 0: self.departments.setSelectedIndex(0) self.total.setText(self.current.total()) def initDepartmentGUI(self): self.grid.clear() self.grid.resize(6, 3) # row 1 self.grid.setWidget(0, 0, Label("Name:")) self.grid.setWidget(1, 0, Label("Manager:")) self.grid.setWidget(2, 0, Label("Department:")) self.grid.setWidget(3, 0, Label("Employee:")) self.grid.setWidget(4, 0, Label("Total:")) # row 2 self.grid.setWidget(0, 1, self.name) self.grid.setWidget(1, 1, self.manager) self.grid.setWidget(2, 1, self.departments) self.grid.setWidget(3, 1, self.employees) self.grid.setWidget(4, 1, self.total) # row 3 self.grid.setWidget(0, 2, self.save) self.grid.setWidget(1, 2, self.edit) self.grid.setWidget(2, 2, self.selectDepartment) self.grid.setWidget(3, 2, self.selectEmployee) self.grid.setWidget(4, 2, self.cut) # back self.grid.setWidget(5, 2, self.back) self.name.setText(self.current.name) self.departments.clear() self.employees.clear() for item in self.current.departments: self.departments.addItem(item.name, item.id) if self.departments.getItemCount() > 0: self.departments.setSelectedIndex(0) for item in self.current.employees: if item.manager == 0: self.employees.addItem(item.name, item.id) else: self.manager.setText(item.name) if self.employees.getItemCount() > 0: self.employees.setSelectedIndex(0) self.total.setText(self.current.total()) def initEmployeeGUI(self): self.grid.clear() self.grid.resize(4, 3) # row 1 self.grid.setWidget(0, 0, Label("Name:")) self.grid.setWidget(1, 0, Label("Address:")) self.grid.setWidget(2, 0, Label("Salary:")) # row 2 self.grid.setWidget(0, 1, self.name) self.grid.setWidget(1, 1, self.address) self.grid.setWidget(2, 1, self.total) # row 3 self.grid.setWidget(0, 2, self.save) self.grid.setWidget(2, 2, self.cut) self.grid.setWidget(3, 2, self.back) self.name.setText(self.current.name) self.address.setText(self.current.address) self.total.setText(self.current.salary)
def onModuleLoad(self): dlp = DockPanel(Width="100%", Height="100%") self.m_rte = RichTextArea(Width="500px", Height="400px") self.m_tb = RichTextToolbar(self.m_rte, self) buts = FlowPanel() self.m_getCurr = Button("Refresh v", self) self.m_setHtml = Button("Set html ^", self) self.m_setHtml.setTitle("Set html from the lower left text area") self.m_toSCursor = Button("< To Cursor", self) self.m_toSCursor.setTitle("Set the selection to be a cursor at the beginning of the current selection") self.m_toECursor = Button("To Cursor >", self) self.m_toECursor.setTitle("Set the selection to be a cursor at the end of the current selection") self.m_surround1 = Button("Surround1", self) self.m_surround2 = Button("Surround2", self) self.m_font1 = Button("Times New Roman", self) self.m_font2 = Button("Arial", self) grid = Grid(2, 2) self.m_startNode = self.createTextBox(1) self.m_startOffset = self.createTextBox(3) self.m_endNode = self.createTextBox(4) self.m_endOffset = self.createTextBox(5) self.m_select = Button("`>Select", self) self.m_select.setTitle("Select the texts/offsets in the boxes above") self.m_cursor = Button("`>Cursor", self) self.m_cursor.setTitle("Set cursor to text/offset of top 2 boxes above") grid.setWidget(0, 0, self.m_startNode) grid.setWidget(0, 1, self.m_startOffset) grid.setWidget(1, 0, self.m_endNode) grid.setWidget(1, 1, self.m_endOffset) self.m_deleteSel = Button("Delete", self) self.m_reset = Button("Reset", self) buts.add(self.m_getCurr) buts.add(self.m_setHtml) buts.add(self.m_toSCursor) buts.add(self.m_toECursor) buts.add(self.m_font1) buts.add(self.m_font2) buts.add(self.m_surround1) buts.add(self.m_surround2) buts.add(grid) buts.add(self.m_select) buts.add(self.m_cursor) buts.add(self.m_deleteSel) buts.add(self.m_reset) dlp.add(buts, DockPanel.WEST) textPanels = DockPanel() self.m_html = TextArea() self.m_html.setSize("100%", "100%") self.m_sel = TextArea() self.m_sel.setSize("100%", "100%") textPanels.add(self.m_sel, DockPanel.EAST) textPanels.add(self.m_html, DockPanel.WEST) dlp.add(textPanels, DockPanel.SOUTH) dlp.add(self.m_tb, DockPanel.NORTH) dlp.add(self.m_rte, DockPanel.CENTER) rp = RootPanel.get() rp.add(dlp) DeferredCommand.add(getattr(self, "set_html_focus")) self.reset()
class Photos(Composite): def __init__(self): Composite.__init__(self) self.albums = [] self.photos = [] self.grid = Grid(4, 4, CellPadding=4, CellSpacing=4) self.grid.addTableListener(self) self.drill = 0 self.pos = 0 self.up = Button("Up", self) self.next = Button("Next", self) self.prev = Button("Prev", self) self.timer = Timer(notify=self) self.userid = "jameskhedley" self.album_url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "?alt=json-in-script&kind=album&hl=en_US&callback=restCb" self.doRESTQuery(self.album_url, self.timer) self.vp = VerticalPanel() self.disclosure = DisclosurePanel("Click for boring technical details.") self.disclosure.add(HTML('''<p>OK so you want to write client JS to do a RESTful HTTP query from picasa right? Well you can't because of the Same Origin Policy. Basically this means that because the domain of the query and the domain of the hosted site are different, then that could well be a cross-site scripting (XSS) attack. So, the workaround is to do the call from a script tag so the JSON we get back is part of the document. But since we don't know what URL to hit yet, once we find out then we have to inject a new script tag dynamically which the browser will run as soon as we append it. To be honest I'm not 100% why Google use RESTful services and not JSON-RPC or somesuch, which would be easier. Well, easier for me.''')) self.IDPanel = HorizontalPanel() self.IDPanel.add(Label("Enter google account:")) self.IDButton = Button("Go", self) self.IDBox = TextBox() self.IDBox.setText(self.userid) self.IDPanel.add(self.IDBox) self.IDPanel.add(self.IDButton) self.vp.add(self.IDPanel) self.vp.add(self.disclosure) self.vp.add(self.grid) self.initWidget(self.vp) def doRESTQuery(self, url, timer): """this is a totally different from an RPC call in that we have to dynamically add script tags to the DOM when we want to query the REST API. These rely on callbacks in the DOM so we can either add them dynamically or pre-define them in public/Main.html. Once we've done that have to wait for the response. Which means we need to provide a listener for the timer""" JS("$wnd.receiver = 'wait'") new_script = DOM.createElement("script") DOM.setElemAttribute(new_script, "src", url) DOM.setElemAttribute(new_script, "type","text/javascript") JS("$wnd.document.body.appendChild(@{{new_script}})") self.timer.schedule(100) def onCellClicked(self, sender, row, col): if self.drill==0: self.drill += 1 self.vp.clear() self.grid.clear() self.vp.add(self.up) self.vp.add(self.grid) gridcols = self.grid.getColumnCount() album = self.albums[row+col+(row*(gridcols-1))] url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "/albumid/" + album["id"] + "?alt=json-in-script&kind=photo&hl=en_US&callback=restCb" self.doRESTQuery(url, self.timer) elif self.drill==1: self.drill += 1 gridcols = self.grid.getColumnCount() self.pos =row+col+(row*(gridcols-1)) photo = self.photos[self.pos] self.vp.clear() self.fullsize = HTML('<img src="' + photo["full"] + '"/>') hp = HorizontalPanel() hp.add(self.up) hp.add(self.prev) hp.add(self.next) hp.setSpacing(8) self.vp.add(hp) self.vp.add(self.fullsize) def onClick(self, sender): if sender == self.IDButton: self.userid = self.IDBox.getText() if self.userid == "" or self.userid.isdigit(): return self.drill = 0 self.album_url = "http://picasaweb.google.com/data/feed/base/user/" + self.userid + "?alt=json-in-script&kind=album&hl=en_US&callback=restCb" self.grid.clear() self.doRESTQuery(self.album_url, self.timer) else: if self.drill == 2: if sender == self.up: self.drill=1 self.vp.clear() self.vp.add(self.up) self.vp.add(self.grid) self.fillGrid(self.photos, "photos") else: if sender == self.next: if self.pos >= len(self.photos): return self.pos +=1 elif sender == self.prev: if self.pos < 1: return self.pos -=1 photo = self.photos[self.pos] self.fullsize.setHTML('<img src="' + photo["full"] + '"/>') elif self.drill == 1: self.drill=0 self.vp.clear() self.vp.add(self.IDPanel) self.vp.add(self.disclosure) self.vp.add(self.grid) self.fillGrid(self.albums, "albums") def onTimer(self, timer): receiver = JS("$wnd.receiver") if receiver == 'wait': self.timer.schedule(1000) return JS("$wnd.receiver = 'wait'") if self.drill == 0: self.parseAlbums(receiver) self.fillGrid(self.albums, "albums") elif self.drill == 1: self.parsePhotos(receiver) self.fillGrid(self.photos, "photos") def fillGrid(self, items, type): self.grid.clear() cols = self.grid.getColumnCount() self.grid.resizeRows((len(items)/cols)+1) rows = self.grid.getRowCount() for i in range(len(items)): vp = VerticalPanel() if type == 'photos': vp.add(items[i]['thumb']) else: vp.add(items[i]['thumb']) vp.add(items[i]['title']) self.grid.setWidget(int(i/cols), i%cols, vp) def parsePhotos(self, items): photo_list = JSONParser().jsObjectToPyObject(items) self.photos = [] for i in range(len(photo_list)): index = "%s" % i aphoto = {} aphoto['thumb'] = HTML('<img src="' + photo_list[index]["media$group"]["media$thumbnail"]["1"]["url"] + '"/>') aphoto['full'] = photo_list[index]["media$group"]["media$content"]["0"]["url"] self.photos.append(aphoto) def parseAlbums(self, items): album_list = JSONParser().jsObjectToPyObject(items) self.albums = [] for i in range(len(album_list)): index = "%s" % i analbum = {} analbum['title'] = HTML(album_list[index]["title"]["$t"]) analbum['thumb'] = HTML('<img src="' + album_list[index]["media$group"]["media$thumbnail"]["0"]["url"] + '"/>') url = album_list[index]["id"]["$t"] analbum['id'] = url.split('albumid/')[1].split('?alt')[0] self.albums.append(analbum)
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 GridWidget(AbsolutePanel): def __init__(self): self.state = State() self.game_round = 0 self.TD_CONSTS = {'c3': 1., 'c2': 1., 'c1': 1., 'c6': 1., 'c5': 1., 'c4': 1.} self.CONSTS = {'c3': .5, 'c2': 1., 'c1': 3., 'c6': .5, 'c5': .5, 'c4': .5} self.BEST_CONSTANTS = {'c3': 0.767944, 'c2': 1.049451, 'c1': 3.074038, 'c6': 0.220823, 'c5': 0.281883, 'c4': 0.605861} self.ONES_CONSTS = {'c3': 1., 'c2': 1., 'c1': 1., 'c6': 1., 'c5': 1., 'c4': 1.} AbsolutePanel.__init__(self) self.welcome_label = HTML('<H2 align="center">Welcome to Meta-Tic-Tac-Toe!</H2>To watch the AI play itself, press either "begin game" button. 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.', StyleName='margins_both') self.add(self.welcome_label) self.depth_limit = 2 self.train_td = Button("Begin game. Learning AI first!", self, StyleName='margins_left') self.add(self.train_td) self.train_static = Button("Begin game. Static AI first!", self, StyleName='margins_left') self.add(self.train_static) self.score_label = Label("CURRENT SCORE: Learning AI: %d | Static AI: %d"% (0,0), StyleName='margins_left') self.add(self.score_label) self.game_over_message = Label("", StyleName='margins_left') self.add(self.game_over_message) StyleSheetCssText(margins) self.increase_depth = Button("Increase ply search depth.", self) self.decrease_depth = Button("Decrease ply search depth.", self) self.depth_label = Label("Current depth is " + str(self.depth_limit) +".") 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) # 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, 4) 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.reset_constants = Button("Reset all of Learning AI's constants to 1.", self, StyleName='margins_left') self.add(self.reset_constants) 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_learning_labels = {} self.adj_static_labels = {} self.incr_buttons = {} td_keys = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] learning_ai_header = Label("Constant for the learning AI.") self.adj_grid.setWidget(0, 0, learning_ai_header) static_ai_header = Label("Constants for the static AI.") self.adj_grid.setWidget(0, 2, static_ai_header) for i, key in enumerate(td_keys): j = i + 1 # off by one because of header... self.adj_learning_labels[key] = Label("Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.adj_grid.setWidget(j, 0, self.adj_learning_labels[key]) self.decr_buttons[key] = Button('<', self) self.adj_grid.setWidget(j, 1, self.decr_buttons[key]) self.adj_static_labels[key] = Label("Constant %d: %f" % (key[1], self.CONSTS[key])) self.adj_grid.setWidget(j, 2, self.adj_static_labels[key]) self.incr_buttons[key] = Button('>', self) self.adj_grid.setWidget(j, 3, self.incr_buttons[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('AI could 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 :( g.state = State() g.game_over = False self.depthLimit = 2 self.human_first = True self.check_is_win() self.max_player = '-1' self.min_player = '-1' self.state_to_grid() def onClick(self, sender): self.check_adjusts(sender) if sender == self.reset_constants: self.TD_CONSTS = self.ONES_CONSTS self.sync_consts() if sender == self.increase_depth: self.depth_limit += 1 self.depth_label.setText("Current depth is " + str(self.depth_limit) +".") if sender == self.decrease_depth: self.depth_limit -= 1 self.depth_label.setText("Current depth is " + str(self.depth_limit) +".") if sender == self.train_td: self.state = State() self.static_ai_str = '2' self.td_ai_str = '1' self.state.next_piece = [1, 1, 1] Timer(250, notify=self.td_ai_turn) if sender == self.train_static: self.state = State() self.static_ai_str = '1' self.td_ai_str = '2' self.state.next_piece = [1, 1, 1] Timer(250, notify=self.static_ai_turn) 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.TD_CONSTS = normalize(self.TD_CONSTS) self.adj_learning_labels[key].setText("Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.sync_consts() def change_td_const(self, key, sign): if sign == '+': self.CONSTS[key] += INCREMENT_AMOUNT elif sign == '-': self.CONSTS[key] -= INCREMENT_AMOUNT def sync_consts(self): """Sync td rates with the current state. """ td_keys = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] for key in td_keys: self.adj_learning_labels[key].setText("Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.adj_static_labels[key].setText("Constant %d: %f" % (key[1], self.CONSTS[key])) def check_is_win(self, last_position={}): 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'],) learning_ai_score = self.state.score[self.td_ai_str] static_ai_score = self.state.score[self.static_ai_str] self.score_label.setText("CURRENT SCORE: Learning AI(%d): %d | Static AI(%d): %d" % (self.td_ai_str, learning_ai_score, self.static_ai_str, static_ai_score)) self.state.printInfo() if is_over(self.state): if learning_ai_score > static_ai_score: msg = "the learning AI won with score %d vs %d." % (learning_ai_score, static_ai_score) elif learning_ai_score < static_ai_score: msg = "the static AI won with score %d vs %d." % (static_ai_score, learning_ai_score) elif learning_ai_score == static_ai_score: msg = "the game ended in a tie." self.game_round += 1 game_over_message.setText("In game round " + str(self.game_round) + ", " + msg) return True else: return False def static_ai_turn(self): print "\n\nNaive AIs turn which plays the piece: ", self.state.next_piece[2] print "next piece is ", self.state.next_piece print "TD_CONSTS", self.TD_CONSTS (expectedUtility, next_state) = ab(self.state, self.CONSTS, depth_limit=self.depth_limit) last_position = find_last_move(self.state, next_state) self.state = next_state self.state.printInfo() over = self.check_is_win(last_position) print "back in static" if not over: self.pause_update = Timer(250, notify=self.td_ai_turn) else: return True def td_ai_turn(self): print "\n\nTD AI player starting turn. TD AI places the piece:", self.state.next_piece[2] print "TD_CONSTS after being adjusted are: ", self.TD_CONSTS # print, alpha-beta search etc.: (expectedUtility, state) = ab(self.state, self.TD_CONSTS, depth_limit=self.depth_limit) terminal_state = expectedUtility.terminal self.TD_CONSTS = td_learning(terminal_state, self.TD_CONSTS, self.state) self.sync_consts() # reflect the new TD_CONSTS in the game. last_position = find_last_move(self.state, state) self.state = state state.printInfo() print "TD_CONSTS after being adjusted are: ", self.TD_CONSTS over = self.check_is_win(last_position) print "back in td" print "Is over ", over if not over: return Timer(250, notify=self.static_ai_turn) else: return True 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: b = HTML('<p style="color:blue">AI %d could<br>play here.</p>' % (self.state.next_piece[2]), self) 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 onModuleLoad(self): dlp = DockPanel(Width="100%", Height="100%") self.m_rte = RichTextArea(Width="500px", Height="400px") self.m_tb = RichTextToolbar(self.m_rte, self) buts = FlowPanel() self.m_getCurr = Button("Refresh v", self) self.m_setHtml = Button("Set html ^", self) self.m_setHtml.setTitle("Set html from the lower left text area") self.m_toSCursor = Button("< To Cursor", self) self.m_toSCursor.setTitle( "Set the selection to be a cursor at the beginning of the current selection" ) self.m_toECursor = Button("To Cursor >", self) self.m_toECursor.setTitle( "Set the selection to be a cursor at the end of the current selection" ) self.m_surround1 = Button("Surround1", self) self.m_surround2 = Button("Surround2", self) self.m_font1 = Button("Times New Roman", self) self.m_font2 = Button("Arial", self) grid = Grid(2, 2) self.m_startNode = self.createTextBox(1) self.m_startOffset = self.createTextBox(3) self.m_endNode = self.createTextBox(4) self.m_endOffset = self.createTextBox(5) self.m_select = Button("`>Select", self) self.m_select.setTitle("Select the texts/offsets in the boxes above") self.m_cursor = Button("`>Cursor", self) self.m_cursor.setTitle( "Set cursor to text/offset of top 2 boxes above") grid.setWidget(0, 0, self.m_startNode) grid.setWidget(0, 1, self.m_startOffset) grid.setWidget(1, 0, self.m_endNode) grid.setWidget(1, 1, self.m_endOffset) self.m_deleteSel = Button("Delete", self) self.m_reset = Button("Reset", self) buts.add(self.m_getCurr) buts.add(self.m_setHtml) buts.add(self.m_toSCursor) buts.add(self.m_toECursor) buts.add(self.m_font1) buts.add(self.m_font2) buts.add(self.m_surround1) buts.add(self.m_surround2) buts.add(grid) buts.add(self.m_select) buts.add(self.m_cursor) buts.add(self.m_deleteSel) buts.add(self.m_reset) dlp.add(buts, DockPanel.WEST) textPanels = DockPanel() self.m_html = TextArea() self.m_html.setSize("100%", "100%") self.m_sel = TextArea() self.m_sel.setSize("100%", "100%") textPanels.add(self.m_sel, DockPanel.EAST) textPanels.add(self.m_html, DockPanel.WEST) dlp.add(textPanels, DockPanel.SOUTH) dlp.add(self.m_tb, DockPanel.NORTH) dlp.add(self.m_rte, DockPanel.CENTER) rp = RootPanel.get() rp.add(dlp) DeferredCommand.add(getattr(self, "set_html_focus")) self.reset()
class Form(FormPanel): def __init__(self, svc, **kwargs): self.describe_listeners = [] if kwargs.has_key('listener'): listener = kwargs.pop('listener') self.addDescribeListener(listener) if kwargs.has_key('data'): data = kwargs.pop('data') else: data = None FormPanel.__init__(self, **kwargs) self.svc = svc self.grid = Grid() self.grid.resize(0, 3) self.add(self.grid) self.describer = FormDescribeGrid(self) self.saver = FormSaveGrid(self) self.getter = FormGetGrid(self) self.formsetup(data) def addDescribeListener(self, l): self.describe_listeners.append(l) def add_widget(self, description, widget): """ adds a widget, with error rows interspersed """ num_rows = self.grid.getRowCount() self.grid.resize((num_rows+1), 3) self.grid.setHTML(num_rows, 0, description) self.grid.setWidget(num_rows, 1, widget) def get(self, **kwargs): writebr(repr(kwargs)) self.svc({}, {'get': kwargs}, self.getter) def save(self, data=None): self.clear_errors() if data is None: data = self.getValue() self.data = data writebr(repr(self.data)) self.svc(data, {'save': None}, self.saver) def save_respond(self, response): if not response['success']: errors = response['errors'] self.set_errors(errors) for l in self.describe_listeners: l.onErrors(self, errors) return for l in self.describe_listeners: l.onSaveDone(self, response) def formsetup(self, data=None): if data is None: data = {} self.data = data self.svc(data, {'describe': None}, self.describer) def clear_errors(self): for idx, fname in enumerate(self.fields): self.grid.setHTML(idx, 2, None) def set_errors(self, errors): offsets = {} for idx, fname in enumerate(self.fields): offsets[fname] = idx for k, err in errors.items(): err = "<br />".join(err) idx = offsets[k] self.grid.setHTML(idx, 2, err) def update_values(self, data = None): if data is not None: self.data = data for idx, fname in enumerate(self.fields): val = None if self.data.has_key(fname): val = self.data[fname] w = self.grid.getWidget(idx, 1) w.setValue(val) def do_get(self, response): fields = response.get('instance', None) if fields: self.update_values(fields) for l in self.describe_listeners: l.onRetrieveDone(self, fields) def do_describe(self, fields): self.fields = fields.keys() for idx, fname in enumerate(self.fields): field = fields[fname] if self.data and self.data.has_key(fname): field['initial'] = self.data[fname] field_type = field['type'] widget_kls = widget_factory.get(field_type, CharField) fv = {} for (k, v) in field.items(): fv[str(k)] = v w = widget_kls(**fv) self.add_widget(field['label'], w) for l in self.describe_listeners: l.onDescribeDone(self) def getValue(self): res = {} for idx, fname in enumerate(self.fields): w = self.grid.getWidget(idx, 1) val = w.getValue() res[fname] = val self.data[fname] = val return res
class InputBox(FocusPanel): _props = [ ("maxLength", "Max Length", "MaxLength", int), ("text", "Text", "Text", None), ("matchPattern", "Match Pattern", "MatchPattern", None), ("cursorStyle", "Cursor Style", "CursorStyle", None), ] @classmethod def _getProps(self): return FocusPanel._getProps() + self._props def __init__(self, **kwargs): """ setMatchPattern - defaults to '' to match everything match pattern examples: '^[0-9]*$' is for digits only '^[0-9,A-Z]*$' is for digits and uppercase setMaxLength setText OB """ kwargs['MatchPattern'] = kwargs.pop('MatchPattern', '') cs = kwargs.pop('CursorStyle', "inputbox-cursor") gs = kwargs.pop('StyleName', 'gwt-inputbox') ap = AbsolutePanel(StyleName="inputbox") self.tp = Grid(StyleName=gs, Width="100%", Height="100%", CellPadding=0, CellSpacing=0) self.cursor = HTML(StyleName=cs) ap.add(self.tp) ap.add(self.cursor, 0, 0) self.cf = self.tp.getCellFormatter() FocusPanel.__init__(self, Widget=ap, **kwargs) self.addTableListener(self) self.addKeyboardListener(self) self.addFocusListener(self) self.word_selected_pos = 0 self.ctimer = Timer(notify=self.cursorFlash) self.focusset = False self.cstate = False self._keypressListeners = [] def addKeypressListener(self, listener): self._keypressListeners.append(listener) def removeKeypressListener(self, listener): self._keypressListeners.remove(listener) def getMatchPattern(self): return self.mp def setMatchPattern(self, mp): self.mp = mp self.rexp = re.compile(self.mp) def addDblTableListener(self, listener): self.tp.addDblTableListener(listener) def addTableListener(self, listener): self.tp.addTableListener(listener) def _move_cursor(self, col): """ moves the css-styled cursor """ #old style (useful for insert mode - don't delete this line for now!) #self.cf.setStyleName(0, col, "inputbox-square-word-cursor", highlight) el = self.cf.getRawElement(0, col+1) w = self.getWidget() px = self.tp.getAbsoluteLeft() py = self.tp.getAbsoluteTop() width = DOM.getOffsetWidth(el) px = DOM.getAbsoluteLeft(el) - px py = DOM.getAbsoluteTop(el) - py w.setWidgetPosition(self.cursor, px, py) def _highlight_cursor(self, col, highlight): """ highlights (or dehighlights) the currently selected cell """ #old style (useful for insert mode - don't delete this line for now!) #self.cf.setStyleName(0, col, "inputbox-square-word-cursor", highlight) print "_highlight", col, highlight self._move_cursor(col) self.cursor.setStyleName("inputbox-square-word-cursor", highlight) def set_grid_value(self, v, y, x): if v: w = "" else: w = "0px" v = v or EMPTY s = HTML(v, StyleName="inputbox-square") self.tp.setWidget(y, x, s) self.cf.setAlignment(y, x, HasAlignment.ALIGN_LEFT, HasAlignment.ALIGN_MIDDLE) self.cf.setWidth(y, x, w) s.setWidth(w) def onKeyDown(self, sender, keycode, modifiers): evt = DOM.eventGetCurrentEvent() DOM.eventPreventDefault(evt) if self.word_selected_pos is None: return val = chr(keycode) done = False if keycode == KeyboardListener.KEY_DELETE: self.shift_letters_back() done = True elif keycode == KeyboardListener.KEY_BACKSPACE: if not self.nasty_hack(): if self.moveCursor(-1): self.shift_letters_back() done = True elif keycode == KeyboardListener.KEY_LEFT: self.moveCursor(-1) done = True elif keycode == KeyboardListener.KEY_RIGHT: self.moveCursor(1) done = True print "onKeyDown", keycode, val, self.rexp.match(val) if not done: if self.rexp.match(val): self.press_letter(val) for listener in self._keypressListeners: listener.onKeyPressed(sender, keycode, modifiers) def press_letter(self, val): print "press letter", val # check the key is a letter, and there's a grid position highlighted if self.word_selected_pos is None: return row = 0 col = self.word_selected_pos self.highlight_cursor(False) self.set_grid_value(val, row, col) self.moveCursor(1) def nasty_hack(self): """ breaking of backspace/delete rules for the final character """ row = 0 col = self.word_selected_pos txt = self.get_char(col) if txt is None or txt == EMPTY: return False self.set_grid_value(EMPTY, row, col) return True def shift_letters_back(self): """ this function is used by del and backspace, to move the letters backwards from after the cursor. the only difference between backspace and delete is that backspace moves the cursor and _then_ does letter-moving. """ self.highlight_cursor(False) row = 0 col = self.word_selected_pos x2 = self.tp.getColumnCount()-2 while (x2 != col): txt = self.get_char(col+1) self.set_grid_value(txt, row, col) col += 1 self.set_grid_value(EMPTY, row, col) def setCursorPos(self, col): x2 = self.tp.getColumnCount()-1 col = min(x2, col) col = max(col, 0) if self.get_char(0) is None or self.get_char(0) == EMPTY: col = 0 while (self.get_char(col-1) is None or \ self.get_char(col-1) == EMPTY) and col > 1: col -= 1 self._move_cursor(col) self.highlight_cursor(False) self.word_selected_pos = col self.highlight_cursor(self.focusset) return True def getCursorPos(self): return self.word_selected_pos def moveCursor(self, dirn): x2 = self.tp.getColumnCount()-1 row = 0 col = self.word_selected_pos if dirn == 1 and x2 == col+1: return False if dirn == -1 and 0 == col+1: return False return self.setCursorPos(col+dirn) def onKeyUp(self, sender, keycode, modifiers): evt = DOM.eventGetCurrentEvent() DOM.eventCancelBubble(evt, True) DOM.eventPreventDefault(evt) def onKeyPress(self, sender, keycode, modifiers): evt = DOM.eventGetCurrentEvent() DOM.eventPreventDefault(evt) def highlight_cursor(self, highlight): """ highlights (or dehighlights) the currently selected cell """ if self.word_selected_pos is None: return col = self.word_selected_pos self._highlight_cursor(col, highlight) def getMaxLength(self): return self.tp.getColumnCount()-1 def setMaxLength(self, x): l = max(0, self.tp.getColumnCount()-1) self.tp.resize(1, x+1) self.clear(l) def clear(self, fromrange=0): for i in range(fromrange, self.tp.getColumnCount()): self.set_grid_value(EMPTY, 0, i) self.cf.setWidth(0, self.tp.getColumnCount()-1, "100%") def onCellClicked(self, listener, row, col, direction=None): self.setCursorPos(col) def cursorFlash(self, timr): if not self.focusset: return self.highlight_cursor(self.cstate) self.cstate = not self.cstate def onFocus(self, sender): print "onFocus", sender self.focusset = True self.ctimer.scheduleRepeating(800) def onLostFocus(self, sender): print "onLostFocus", sender self.focusset = False self.ctimer.cancel() self.highlight_cursor(False) def get_char(self, x): w = self.tp.getWidget(0, x) return w and w.getHTML() def getText(self): txt = '' for i in range(self.tp.getColumnCount()-1): c = self.get_char(i) if c is None or c == EMPTY: break txt += c return txt def setText(self, txt): self.highlight_cursor(False) self.clear() txt = txt[:self.getMaxLength()] for (i, c) in enumerate(txt): self.set_grid_value(c, 0, i) self.setCursorPos(min(self.getMaxLength()-1, len(txt)))
class GridWidget(AbsolutePanel): def __init__(self): self.state = State() self.game_round = 0 self.TD_CONSTS = { 'c3': 1., 'c2': 1., 'c1': 1., 'c6': 1., 'c5': 1., 'c4': 1. } self.CONSTS = { 'c3': .5, 'c2': 1., 'c1': 3., 'c6': .5, 'c5': .5, 'c4': .5 } self.BEST_CONSTANTS = { 'c3': 0.767944, 'c2': 1.049451, 'c1': 3.074038, 'c6': 0.220823, 'c5': 0.281883, 'c4': 0.605861 } self.ONES_CONSTS = { 'c3': 1., 'c2': 1., 'c1': 1., 'c6': 1., 'c5': 1., 'c4': 1. } AbsolutePanel.__init__(self) self.welcome_label = HTML( '<H2 align="center">Welcome to Meta-Tic-Tac-Toe!</H2>To watch the AI play itself, press either "begin game" button. 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.', StyleName='margins_both') self.add(self.welcome_label) self.depth_limit = 2 self.train_td = Button("Begin game. Learning AI first!", self, StyleName='margins_left') self.add(self.train_td) self.train_static = Button("Begin game. Static AI first!", self, StyleName='margins_left') self.add(self.train_static) self.score_label = Label( "CURRENT SCORE: Learning AI: %d | Static AI: %d" % (0, 0), StyleName='margins_left') self.add(self.score_label) self.game_over_message = Label("", StyleName='margins_left') self.add(self.game_over_message) StyleSheetCssText(margins) self.increase_depth = Button("Increase ply search depth.", self) self.decrease_depth = Button("Decrease ply search depth.", self) self.depth_label = Label("Current depth is " + str(self.depth_limit) + ".") 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) # 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, 4) 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.reset_constants = Button( "Reset all of Learning AI's constants to 1.", self, StyleName='margins_left') self.add(self.reset_constants) 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_learning_labels = {} self.adj_static_labels = {} self.incr_buttons = {} td_keys = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] learning_ai_header = Label("Constant for the learning AI.") self.adj_grid.setWidget(0, 0, learning_ai_header) static_ai_header = Label("Constants for the static AI.") self.adj_grid.setWidget(0, 2, static_ai_header) for i, key in enumerate(td_keys): j = i + 1 # off by one because of header... self.adj_learning_labels[key] = Label( "Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.adj_grid.setWidget(j, 0, self.adj_learning_labels[key]) self.decr_buttons[key] = Button('<', self) self.adj_grid.setWidget(j, 1, self.decr_buttons[key]) self.adj_static_labels[key] = Label("Constant %d: %f" % (key[1], self.CONSTS[key])) self.adj_grid.setWidget(j, 2, self.adj_static_labels[key]) self.incr_buttons[key] = Button('>', self) self.adj_grid.setWidget(j, 3, self.incr_buttons[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('AI could 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 :( g.state = State() g.game_over = False self.depthLimit = 2 self.human_first = True self.check_is_win() self.max_player = '-1' self.min_player = '-1' self.state_to_grid() def onClick(self, sender): self.check_adjusts(sender) if sender == self.reset_constants: self.TD_CONSTS = self.ONES_CONSTS self.sync_consts() if sender == self.increase_depth: self.depth_limit += 1 self.depth_label.setText("Current depth is " + str(self.depth_limit) + ".") if sender == self.decrease_depth: self.depth_limit -= 1 self.depth_label.setText("Current depth is " + str(self.depth_limit) + ".") if sender == self.train_td: self.state = State() self.static_ai_str = '2' self.td_ai_str = '1' self.state.next_piece = [1, 1, 1] Timer(250, notify=self.td_ai_turn) if sender == self.train_static: self.state = State() self.static_ai_str = '1' self.td_ai_str = '2' self.state.next_piece = [1, 1, 1] Timer(250, notify=self.static_ai_turn) 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.TD_CONSTS = normalize(self.TD_CONSTS) self.adj_learning_labels[key].setText( "Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.sync_consts() def change_td_const(self, key, sign): if sign == '+': self.CONSTS[key] += INCREMENT_AMOUNT elif sign == '-': self.CONSTS[key] -= INCREMENT_AMOUNT def sync_consts(self): """Sync td rates with the current state. """ td_keys = ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'] for key in td_keys: self.adj_learning_labels[key].setText( "Constant %d: %f" % (key[1], self.TD_CONSTS[key])) self.adj_static_labels[key].setText("Constant %d: %f" % (key[1], self.CONSTS[key])) def check_is_win(self, last_position={}): 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'], ) learning_ai_score = self.state.score[self.td_ai_str] static_ai_score = self.state.score[self.static_ai_str] self.score_label.setText( "CURRENT SCORE: Learning AI(%d): %d | Static AI(%d): %d" % (self.td_ai_str, learning_ai_score, self.static_ai_str, static_ai_score)) self.state.printInfo() if is_over(self.state): if learning_ai_score > static_ai_score: msg = "the learning AI won with score %d vs %d." % ( learning_ai_score, static_ai_score) elif learning_ai_score < static_ai_score: msg = "the static AI won with score %d vs %d." % ( static_ai_score, learning_ai_score) elif learning_ai_score == static_ai_score: msg = "the game ended in a tie." self.game_round += 1 game_over_message.setText("In game round " + str(self.game_round) + ", " + msg) return True else: return False def static_ai_turn(self): print "\n\nNaive AIs turn which plays the piece: ", self.state.next_piece[ 2] print "next piece is ", self.state.next_piece print "TD_CONSTS", self.TD_CONSTS (expectedUtility, next_state) = ab(self.state, self.CONSTS, depth_limit=self.depth_limit) last_position = find_last_move(self.state, next_state) self.state = next_state self.state.printInfo() over = self.check_is_win(last_position) print "back in static" if not over: self.pause_update = Timer(250, notify=self.td_ai_turn) else: return True def td_ai_turn(self): print "\n\nTD AI player starting turn. TD AI places the piece:", self.state.next_piece[ 2] print "TD_CONSTS after being adjusted are: ", self.TD_CONSTS # print, alpha-beta search etc.: (expectedUtility, state) = ab(self.state, self.TD_CONSTS, depth_limit=self.depth_limit) terminal_state = expectedUtility.terminal self.TD_CONSTS = td_learning(terminal_state, self.TD_CONSTS, self.state) self.sync_consts() # reflect the new TD_CONSTS in the game. last_position = find_last_move(self.state, state) self.state = state state.printInfo() print "TD_CONSTS after being adjusted are: ", self.TD_CONSTS over = self.check_is_win(last_position) print "back in td" print "Is over ", over if not over: return Timer(250, notify=self.static_ai_turn) else: return True 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: b = HTML( '<p style="color:blue">AI %d could<br>play here.</p>' % (self.state.next_piece[2]), self) 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 __init__(self): # layed out in a grid with odd rows a different color for # visual separation grid = Grid(4,3,CellPadding=50,CellSpacing=0) rf = grid.getRowFormatter() rf.setStyleName(1, 'oddrow') rf.setStyleName(3, 'oddrow') # the clock clock = Clock() grid.setWidget(0, 0, CaptionPanel('Using notify()', clock.button, StyleName='left')) grid.setWidget(0, 1, clock.datelabel) grid.setWidget(0, 2, HTML(Clock.__doc__, StyleName='desc')) # popup timer buttons ptb = PopupTimerButton(5) grid.setWidget(1, 0, CaptionPanel('Subclassing Timer()', ptb, StyleName='left')) grid.setWidget(1, 1, ptb.box) grid.setWidget(1, 2, HTML(PopupTimerButton.__doc__, StyleName='desc')) # the second instance ptb = PopupTimerButton(15) grid.setWidget(2, 0, CaptionPanel('Subclassing Timer() (<em>again</em>)', ptb, StyleName='left')) grid.setWidget(2, 1, ptb.box) grid.setWidget(2, 2, HTML('''This is the same as the previous example and is here to demonstrate creating multiple timers (each with their own state) which is difficult to do without sublcassing''', StyleName='desc')) # random color randomcolor = RandomColor() grid.setWidget(3, 0, CaptionPanel('Using onTimer()', randomcolor.hpanel, StyleName='left')) grid.setWidget(3, 1, randomcolor.colorpanel) grid.setWidget(3, 2, HTML(RandomColor.__doc__, StyleName='desc')) # add it all to the root panel RootPanel().add(grid) # kickstart the slider handle (see above concerning a # potential bug) randomcolor.initialize()
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)
class PopupPagina(PopupPanel): def __init__(self, autoHide=None, modal=True, **kwargs): PopupPanel.__init__(self, autoHide, modal, **kwargs) datasource = None id = None if kwargs.has_key("datasrc"): datasource = kwargs["datasrc"] if kwargs.has_key("id"): id = kwargs["id"] self.setSize(Window.getClientWidth() - 50, Window.getClientHeight() - 50) self.setPopupPosition(20, 0) DOM.setAttribute(self, "align", "center") # self.dbProxInstrucao = DialogBox() # self.dbProxInstrucao.setHTML("Alow") # botton = Button("Ok") # botton.addClickListener(self.onCloseDialog) # self.dbProxInstrucao.setWidget(botton) self.caption = HTML() self.child = None self.setHTML("<b>Soma de Matrizes.</b>") self.dragging = False self.dragStartX = 0 self.dragStartY = 0 self.imageFechar = Image("images/fechar.gif", Size=("32px", "32px"), StyleName="gwt-ImageButton") self.imgbtnDesfazer = Image("images/previous-arrow.png", Size=("32px", "20px"), StyleName="gwt-ImageButton") self.imgbtnFazer = Image("images/next-arrow.png", Size=("32px", "20px"), StyleName="gwt-ImageButton") # self.imgbtnDesfazer.addClickListener(desfazerProxOperacao) # self.imgbtnFazer.addClickListener(fazerProxOperacao) self.btnAutomatic = Button("Automático", self.onIniciarAnimacaoAutomatica) self.btnInterativo = Button("Interativo") if id == "escalar": self.btnStepByStep = Button("Passo a passo", IniciarAnimacaoPassoAPasso) else: self.btnStepByStep = Button("Passo a passo", self.onIniciarAnimacaoPassoAPasso) self.btnFazer = Button("fazer >>", fazerProxOperacao) # self.btnFazer.setEnabled(False); self.btnDesfazer = Button("<< desfazer", desfazerProxOperacao) # self.btnDesfazer.setEnabled(False); self.btnFechar = PushButton(imageFechar, imageFechar) self.btnTestarResposta = Button("Testar Solução") self.lbVelocidade = ListBox() self.lbVelocidade.setID("lbseg") self.lbVelocidade.addItem("0.5 segundo", value=2) self.lbVelocidade.addItem("1 segundo", value=1) self.lbVelocidade.addItem("2 segundos", value=0.5) self.lbVelocidade.addItem("3 segundos", value=1 / 3) self.lbVelocidade.addItem("4 segundos", value=0.25) self.lbVelocidade.addItem("5 segundos", value=0.20) self.lbVelocidade.addItem("6 segundos", value=0.167) self.lbVelocidade.addItem("7 segundos", value=0.143) self.lbVelocidade.addItem("8 segundos", value=0.125) self.lbVelocidade.addItem("10 segundos", value=0.1) lblinha1 = ListBox() lblinha1.setID("lm1") lblinha1.addItem("1", value=1) lblinha1.addItem("2", value=2) lblinha1.addItem("3", value=3) lblinha1.addItem("4", value=4) lblinha1.addItem("5", value=5) lblinha2 = ListBox() lblinha2.setID("lm2") lblinha2.addItem("1", value=1) lblinha2.addItem("2", value=2) lblinha2.addItem("3", value=3) lblinha2.addItem("4", value=4) lblinha2.addItem("5", value=5) lbcoluna1 = ListBox() lbcoluna1.setID("cm1") lbcoluna1.addItem("1", value=1) lbcoluna1.addItem("2", value=2) lbcoluna1.addItem("3", value=3) lbcoluna1.addItem("4", value=4) lbcoluna1.addItem("5", value=5) lbcoluna1.addItem("6", value=6) lbcoluna1.addItem("7", value=7) lbcoluna2 = ListBox() lbcoluna2.setID("cm2") lbcoluna2.addItem("1", value=1) lbcoluna2.addItem("2", value=2) lbcoluna2.addItem("3", value=3) lbcoluna2.addItem("4", value=4) lbcoluna2.addItem("5", value=5) lbcoluna2.addItem("6", value=6) lbcoluna2.addItem("7", value=7) self.lblStatus = Label("Label para Status") # Eventos self.imageFechar.addClickListener(self.onFecharPopup) # Cabeçalho da poupPanel self.grid = Grid(1, 16) self.grid.setWidth(self.getWidth()) self.grid.setHTML(0, 0, "<b>Matriz 1:</b> Nº Linhas:") self.grid.setWidget(0, 1, lblinha1) self.grid.setText(0, 2, "Nº Colunas:") self.grid.setWidget(0, 3, lbcoluna1) self.grid.setHTML(0, 4, "<b>Matriz 2:</b> Nº Linhas:") self.grid.setWidget(0, 5, lblinha2) self.grid.setText(0, 6, "Nº Colunas:") self.grid.setWidget(0, 7, lbcoluna2) # self.grid.setWidget(0, 3, self.txtColunas) self.grid.setWidget(0, 8, self.btnStepByStep) self.grid.setWidget(0, 9, self.btnDesfazer) self.grid.setWidget(0, 10, self.btnFazer) self.grid.setHTML(0, 11, "<b>Velocidade:</b>") self.grid.setWidget(0, 12, self.lbVelocidade) self.grid.setWidget(0, 13, self.btnAutomatic) # self.grid.setWidget(0, 14, self.btnInterativo) self.grid.setWidget(0, 15, self.imageFechar) # self.grid.setWidget(0, 7, self.btnFechar) self.grid.getCellFormatter().setAlignment( 0, 15, HasHorizontalAlignment.ALIGN_RIGHT, HasVerticalAlignment.ALIGN_TOP ) self.panel = FlexTable(Height="100%", width="100%", BorderWidth="0", CellPadding="0", CellSpacing="0") self.panel.setWidget(0, 0, self.caption) self.panel.setWidget(1, 0, self.grid) self.panel.getCellFormatter().setHeight(2, 0, "100%") self.panel.getCellFormatter().setWidth(2, 0, "100%") self.panel.getCellFormatter().setAlignment( 2, 0, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_TOP ) self.panel.setID("contetepopup") painelhorizontal = HorizontalPanel() gridinterativa = FlexTable() painelhorizontal.add( HTML( "<canvas id='%s' datasrc='%s' width='%s' height='%s' style='image-rendering: optimizespeed !important; '></canvas>" % ("soma", datasource, "1000px", "500px") ) ) ftInterativo = FlexTable(Height="100%", width="100%", BorderWidth="0", CellPadding="0", CellSpacing="0") gridinterativa = Grid(4, 4) gridinterativa.setWidget( 0, 0, HTML( "<b>M1(</b><input type='text' class='gwt-TextBox' id='linha1' style='width: 25px; height:20px;' maxLength='1'><b> , </b>" ), ) gridinterativa.setWidget( 0, 1, HTML( "<input type='text' class='gwt-TextBox' id='coluna1' style='width: 25px;height:20px;' maxLength='1'><b>) +</b>" ), ) gridinterativa.setWidget( 0, 2, HTML( "<b>M2(</b> <input type='text' class='gwt-TextBox' id='linha2' style='width: 25px; height:20px;' maxLength='1'><b> , </b>" ), ) gridinterativa.setWidget( 0, 3, HTML( "<input type='text' class='gwt-TextBox' id='coluna2' style='width: 25px; height:20px;' maxLength='1'><b>) =</b>" ), ) gridinterativa.setWidget( 2, 0, HTML( " <b>(</b><input type='text' class='gwt-TextBox' id='n1' style='width: 25px; height:20px;' maxLength='1'><b>) +</b>" ), ) gridinterativa.setWidget( 2, 1, HTML( "<b>(</b><input type='text' class='gwt-TextBox' id='n2' style='width: 25px; height:20px;' maxLength='1'><b>)</b>" ), ) gridinterativa.setWidget( 2, 2, HTML( "<b>= </b> <input type='text' class='gwt-TextBox' id='solucao' style='width: 25px; height:20px;' maxLength='1'>" ), ) ftInterativo.setHTML(0, 0, "</br>") ftInterativo.setHTML(1, 0, "<b><h3>Painel Interativo<h3></b>") # ftInterativo.setWidget(2, 0, self.btnInterativo) ftInterativo.setWidget(3, 0, gridinterativa) ftInterativo.setWidget(4, 0, self.btnTestarResposta) ftInterativo.setHTML(5, 0, "</br>") ftInterativo.setHTML(6, 0, "Use a tecla tab para agilizar.") ftInterativo.getCellFormatter().setAlignment( 4, 0, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_TOP ) ftInterativo.getCellFormatter().setAlignment( 1, 0, HasHorizontalAlignment.ALIGN_CENTER, HasVerticalAlignment.ALIGN_TOP ) # painelhorizontal.add(ftInterativo) self.panel.setWidget(2, 0, painelhorizontal) self.panel.setWidget(3, 0, self.lblStatus) self.panel.setStyleName("dialogContent") PopupPanel.setWidget(self, self.panel) self.setStyleName("gwt-DialogBox") self.caption.setStyleName("Caption") self.caption.addMouseListener(self) # self.txtlm1.setFocus(True); def onFecharPopup(self, event): self.hide() PararAnimacao() def onIniciarAnimacaoPassoAPasso(self, event): self.btnFazer.setEnabled(True) self.btnDesfazer.setEnabled(True) if self.validarParametrosMatriz(): IniciarAnimacaoPassoAPasso() def onIniciarAnimacaoAutomatica(self, event): if self.validarParametrosMatriz(): IniciarAnimacaoAutomatica() def onTestarSolucao(self, event): pass # if self.validarParametrosMatriz(): # def onCloseDialog(self, event): # self.dbProxInstrucao.hide() # def onOpenDialog(self, event): # self.dbProxInstrucao.show() def validarParametrosTestarSolucao(): lm1 = DOM.getElementById("linha1") lm1 = lm1.value cm1 = DOM.getElementById("coluna1") cm1 = cm1.value lm2 = DOM.getElementById("linha2") lm2 = lm2.value cm2 = DOM.getElementById("coluna2") cm2 = cm2.value def validarParametrosMatriz(): lm1 = DOM.getElementById("lm1") lm1 = lm1.value cm1 = DOM.getElementById("cm1") cm1 = cm1.value lm2 = DOM.getElementById("lm2") lm2 = lm2.value cm2 = DOM.getElementById("cm2") cm2 = cm2.value if not lm1 or not lm2: Window.alert("Informe o numero de linhas da matriz M1 e M2.") return False if lm1 != lm2: Window.alert("A quantidade de linhas da matriz M1 deve ser igual a da matriz M2 para operação de soma.") return False if lm1 > "5" or lm2 > "5" or len(lm1) != 1 or len(lm2) != 1: Window.alert("A quantidade de linhas da matriz M1 e da matriz M2, deve ser menor ou igual a 5.") return False if not cm1 or not cm2: Window.alert("Informe o numero de colunas da matriz M1 e M2.") return False if cm1 != cm2: Window.alert("A quantidade de colunas da matriz M1 deve ser igual a da matriz M2 para operação de soma.") return False if cm1 > "7" or cm2 > "7" or len(cm1) != 1 or len(cm2) != 1: Window.alert("A quantidade de colunas da matriz M1 e da matriz M2, deve ser menor ou igual a 7.") return False return True def getHTML(self): return self.caption.getHTML() def getText(self): return self.caption.getText() def onEventPreview(self, event): # preventDefault on mousedown events, outside of the # dialog, to stop text-selection on dragging type = DOM.eventGetType(event) if type == "mousedown": target = DOM.eventGetTarget(event) elem = self.caption.getElement() event_targets_popup = target and DOM.isOrHasChild(elem, target) if event_targets_popup: DOM.eventPreventDefault(event) return PopupPanel.onEventPreview(self, event) def onMouseDown(self, sender, x, y): self.dragging = True DOM.setCapture(self.caption.getElement()) self.dragStartX = x self.dragStartY = y def onMouseMove(self, sender, x, y): if self.dragging: absX = x + self.getAbsoluteLeft() absY = y + self.getAbsoluteTop() self.setPopupPosition(absX - self.dragStartX, absY - self.dragStartY) def onMouseUp(self, sender, x, y): self.dragging = False DOM.releaseCapture(self.caption.getElement()) def onMouseLeave(self, self, x, y): pass def onMouseEnter(self, self, x, y): pass def remove(self, widget): if self.child != widget: return False self.panel.remove(widget) self.child = None return True def setHTML(self, html): self.caption.setHTML(html) def setText(self, text): self.caption.setText(text) def doAttachChildren(self): PopupPanel.doAttachChildren(self) self.caption.onAttach() def doDetachChildren(self): PopupPanel.doDetachChildren(self) self.caption.onDetach() def setWidget(self, widget): if self.child is not None: self.panel.remove(self.child) if widget is not None: self.panel.setWidget(1, 0, widget) self.child = widget
def __init__(self, statusSummary, sender): VerticalPanel.__init__(self, Spacing=10, StyleName='userlist-error-box') self.add(HTML("We're currently working on users you mentioned", StyleName='userlist-error-title')) self.add(HTML( """<p>Below is a summary of work already in progress, or queued, which must complete before we can run your query. Please note that Tickery is subject to Twitter's API rate limiting and general network latency, so you may need to be patient. We'll get there!</p> <p><a href=\"%s\">Here's a link</a> to this results page so you can come back to see how we're doing. You can also click %r again to see updated progress.</p>""" % (sender.resultsLink(), go.goButtonText), StyleName='userlist-error-text')) nRows = 0 underway = statusSummary['underway'] nUnderway = len(underway) queued = statusSummary['queued'] nQueued = len(queued) nCols = 4 width = 200 if nUnderway: nRows += nUnderway + 1 if nQueued: nRows += nQueued + 1 g = Grid(nRows, nCols, StyleName='users') g.setCellPadding(2) cellFormatter = g.getCellFormatter() row = 0 if nUnderway: g.setHTML(row, 0, 'Users currently being processed ') cellFormatter.setStyleName(row, 0, 'title-lhs') g.setText(row, 1, 'Name') cellFormatter.setStyleName(row, 1, 'title') g.setText(row, 2, 'Friends') cellFormatter.setStyleName(row, 2, 'title') g.setText(row, 3, '% done') cellFormatter.setStyleName(row, 3, 'title') cellFormatter.setWidth(row, 3, width) row += 1 for u, nFriends, done in underway: cellFormatter.setStyleName(row, 0, 'blank') n = utils.splitthousands(nFriends) g.setHTML(row, 1, utils.screennameToTwitterLink(u)) g.setHTML(row, 2, utils.screennameToTwitterFriendsLink(u, n)) cellFormatter.setHorizontalAlignment(row, 2, 'right') pct = '%d' % int(done * 100.0) left = Label(pct, StyleName='done', Width=int(done * width)) g.setWidget(row, 3, left) row += 1 if nQueued: g.setHTML(row, 0, 'Users queued for processing ') cellFormatter.setStyleName(row, 0, 'title-lhs') g.setText(row, 1, 'Name') cellFormatter.setStyleName(row, 1, 'title') g.setText(row, 2, 'Friends') cellFormatter.setStyleName(row, 2, 'title') g.setText(row, 3, 'Queue position') cellFormatter.setStyleName(row, 3, 'title') row += 1 for u, nFriends, pos in queued: cellFormatter.setStyleName(row, 0, 'blank') n = utils.splitthousands(nFriends) g.setHTML(row, 1, utils.screennameToTwitterLink(u)) g.setHTML(row, 2, utils.screennameToTwitterFriendsLink(u, n)) cellFormatter.setHorizontalAlignment(row, 2, 'right') g.setText(row, 3, pos) cellFormatter.setHorizontalAlignment(row, 3, 'right') row += 1 self.add(g)