class Player: def __init__(self, activity, is_inverted, solved_callback): """ Initialize. :param activity: the main activity for the app :param is_inverted: True if this player should be displayed upside down :param solved_callback: to call when the sentence is solved - solved_callback(player)""" self.activity = activity self.is_inverted = is_inverted self.solved_callback = solved_callback self.solution_buttons = [] self.shelf_buttons = [] self.solution_sources = [] self.opponent = None self.unlimited_hints = False self.top_label = None self.next_button = None self.solution_label = None self.sentence = None self.shelf_layout = self.solution_layout = self.top_layout = None def on_create(self, parent_layout): vlayout = LinearLayout(self.activity) vlayout.setOrientation(LinearLayout.VERTICAL) vlayout.setGravity(Gravity.BOTTOM) if self.is_inverted: vlayout.setRotation(180) parent_layout.addView(vlayout) self.top_layout = LinearLayout(self.activity) self.top_layout.setOrientation(LinearLayout.HORIZONTAL) self.top_label = TextView(self.activity) # noinspection PyUnresolvedReferences self.top_label.setLayoutParams( LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 1)) self.top_label.setTextSize(50) self.top_layout.addView(self.top_label) self.next_button = Button(self.activity) # noinspection PyUnresolvedReferences self.next_button.setLayoutParams( LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 0)) self.next_button.setText('Hint') self.next_button.setOnClickListener(ButtonClick(self.next)) self.top_layout.addView(self.next_button) vlayout.addView(self.top_layout) self.solution_layout = LinearLayout(self.activity) self.solution_layout.setOrientation(LinearLayout.HORIZONTAL) self.solution_layout.setGravity(Gravity.LEFT) self.solution_label = TextView(self.activity) self.solution_label.setText('') self.solution_label.setTextSize(50) self.solution_layout.addView(self.solution_label) vlayout.addView(self.solution_layout) self.shelf_layout = LinearLayout(self.activity) self.shelf_layout.setOrientation(LinearLayout.HORIZONTAL) self.shelf_layout.setGravity(Gravity.CENTER) vlayout.addView(self.shelf_layout) def set_sentence(self, sentence): self.sentence = sentence self.top_label.setText(self.sentence.translation) self.solution_label.setText('') button_count = len(self.sentence.source) while self.shelf_layout.getChildCount() > button_count: self.shelf_layout.removeViewAt(0) self.shelf_buttons.pop(0) self.solution_layout.removeViewAt(1) self.solution_buttons.pop(0) while self.shelf_layout.getChildCount() < button_count: self.add_button(self.shelf_layout, self.shelf_buttons) self.add_button(self.solution_layout, self.solution_buttons) self.update_display() def update_display(self): self.update_buttons(self.solution_buttons, self.sentence.selected, self.sentence.hint_size) self.update_buttons(self.shelf_buttons, self.sentence.source) if self.sentence.is_solved: self.next_button.setText('Next') self.next_button.setEnabled(True) # noinspection PyMethodMayBeStatic def update_buttons(self, buttons, characters, disabled_count=0): for i, (button, text) in enumerate(zip(buttons, characters)): button.setEnabled(i >= disabled_count) button.setText(text) button.setVisibility(button.INVISIBLE if text == ' ' else button.VISIBLE) def add_button(self, layout, button_list): button = Button(self.activity) button.setTextSize(50) layout.addView(button) button_list.append(button) button.setOnClickListener(ButtonClick(self.move_button, button)) def move_button(self, button): if button in self.solution_buttons: solution_index = self.solution_buttons.index(button) self.sentence.replace(solution_index) else: source_index = self.shelf_buttons.index(button) self.sentence.select(source_index) self.update_display() if self.sentence.is_solved: self.solution_label.setText(self.sentence.text) for b in self.solution_buttons: b.setVisibility(b.INVISIBLE) def get_buttons(self): buttons = [button.getText() for button in self.solution_sources] return buttons def enable_hint(self): self.next_button.setEnabled(True) def next(self): self.next_button.setEnabled(self.unlimited_hints) self.opponent.enable_hint() if self.sentence.is_solved: self.next_button.setText('Hint') self.solved_callback(self) else: self.sentence.get_hint() self.update_display()
class TranslateOffApp: def __init__(self): self._activity = android.PythonActivity.setListener(self) self.players = [] self.player_progress = None self.sentence_pairs = None self.winner_label = None self.next_button = None self.random = Random() def onCreate(self): sentence_lines = iter(sentence_text.splitlines()) all_sentence_pairs = list(zip(sentence_lines, sentence_lines)) self.sentence_pairs = [] while len(self.sentence_pairs) < 10 and all_sentence_pairs: # noinspection PyUnresolvedReferences i = self.random.nextInt(len(all_sentence_pairs)) sentence_pair = all_sentence_pairs.pop(i) if len(sentence_pair[0]) <= 9: self.sentence_pairs.append(sentence_pair) self.players = [ Player(self._activity, is_inverted, self.on_solved) for is_inverted in (True, False) ] self.player_progress = {player: 0 for player in self.players} vlayout = LinearLayout(self._activity) vlayout.setOrientation(LinearLayout.VERTICAL) for i, player in enumerate(self.players): if i: self.winner_label = TextView(self._activity) self.winner_label.setTextSize(50) # noinspection PyUnresolvedReferences self.winner_label.setLayoutParams( LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, 1)) vlayout.addView(self.winner_label) player.opponent = self.players[(i + 1) % 2] player.on_create(vlayout) self.set_sentence(player) self._activity.setContentView(vlayout) def set_sentence(self, player): i = self.player_progress[player] text, translation = self.sentence_pairs[i] player.set_sentence( Sentence(text, translation, randrange=self.random.nextInt)) def on_solved(self, player): i = self.player_progress[player] + 1 if i < len(self.sentence_pairs): self.player_progress[player] = i self.set_sentence(player) else: if self.winner_label.getText(): return if player.is_inverted: self.winner_label.setRotation(180) else: self.winner_label.setRotation(0) self.winner_label.setText('You Win!') player.opponent.unlimited_hints = True