File: state.py

package info (click to toggle)
pybik 0.5-1
  • links: PTS
  • area: main
  • in suites: wheezy
  • size: 776 kB
  • sloc: python: 4,591; makefile: 4; sh: 1
file content (160 lines) | stat: -rw-r--r-- 6,207 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#-*- coding:utf-8 -*-

#  Pybik -- A 3 dimensional magic cube game.
#  Copyright © 2009-2011  B. Clausius <barcc@gmx.de>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.


# Ported from GNUbik
# Original filename: ui.c
# Original copyright and license: GPL3+
#                  1998,  2003  John Darrington
#                  2004  John Darrington,  Dale Mellor


from .debug import *

from . import cube_form
from . import move_queue


# The move taking place NOW
class CurrentMovement:
    def __init__(self):
        self.mark_before = False
        self.initial_cube_state = cube_form.CubeState()
        self.current_cube_state = cube_form.CubeState()
        self.all_moves = move_queue.MoveQueue()
        
    def set_saved_game(self, dimension, saved_state, saved_moves, saved_pos):
        self.initial_cube_state.set_solved(dimension=dimension)
        try:
            self.initial_cube_state.parse_block(saved_state)
        except Exception as e:
            debug('Error parsing saved cube state: ', e)
            self.current_cube_state = self.initial_cube_state.copy()
        else:
            self.current_cube_state = self.initial_cube_state.copy()
            self.all_moves.reset()
            pos = self.all_moves.parse(saved_moves, saved_pos, dimension)
            self.do_fast_forward(to_pos=pos)
            
    def get_saved_game(self):
        dimension = self.initial_cube_state.dimension
        saved_state = self.initial_cube_state.format_block_compact()
        saved_moves, saved_pos, unused_markup = self.all_moves.format(dimension)
        return dimension, saved_state, saved_moves, saved_pos
        
    def set_solved(self, dimension):
        self.initial_cube_state.set_solved(dimension=dimension)
        self.current_cube_state = self.initial_cube_state.copy()
        
    def set_random(self, dimension):
        self.initial_cube_state.set_solved(dimension=dimension)
        self.initial_cube_state.randomize_and_apply()
        self.current_cube_state = self.initial_cube_state.copy()
        
    ### Funktions to control the cube for use in callbacks and scripts
    
    def request_back(self):
        '''One step back in the sequence of moves'''
        if self.all_moves.at_start():
            return None
        self.all_moves.retard()
        move_data = self.all_moves.current().copy()
        self.current_cube_state.rotate_slice_back(move_data)
        move_data.dir = not move_data.dir
        self.mark_before = move_data.mark_after
        return move_data
            
    # Internal functionality for the following two functions.
    def _request_play(self, one_move):
        move_data = self.all_moves.current()
        if move_data:
            self.mark_before = self.all_moves.at_start() or self.all_moves.prev().mark_after
            self.current_cube_state.rotate_slice(move_data)
            self.all_moves.advance()
        return move_data
            
    def request_play(self):
        '''Play the current sequence of moves to the end'''
        move_data = self._request_play(0)
        return move_data
        
    def request_next(self):
        '''One step forward in the sequence of moves'''
        return self._request_play(1)
        
    def request_rotation(self, maxis, mslice, mdir):
        '''Make one new move.
        
        The usual rotation request,  called when user uses mouse to rotate the cube by
        hand. The move is put into the `current' place,  and all the moves in
        all_moves afterwards are zapped.'''
        move_data = move_queue.MoveData(maxis, mslice, mdir)
        self.all_moves.push_current(move_data)
        
    def request_mark_move_queue(self, mark):
        '''Set a marker at the current position in the sequence of moves'''
        self.all_moves.mark_current(mark)
        
    def do_rewind_to_mark(self):
        if self.all_moves.at_start():
            return False
        move_data = self.all_moves.prev()
        while True:
            self.all_moves.retard()
            self.current_cube_state.rotate_slice_back(move_data)
            if self.all_moves.at_start():
                break
            move_data = self.all_moves.prev()
            if move_data.mark_after:
                break
        return True
        
    def do_fast_forward(self, to_pos=-1):
        '''Go to end of the sequence of moves.
        
        All the moves take place on the cube,  not via the animation
        routines,  so the effect is to show the result instantaneously.'''
        move_data = self.all_moves.current()
        while move_data:
            if to_pos == self.all_moves.current_place:
                break
            self.current_cube_state.rotate_slice(move_data)
            self.all_moves.advance()
            if to_pos < 0 and move_data.mark_after:
                break
            move_data = self.all_moves.current()
        
    def set_from_formula(self, code, pos):
        self.current_cube_state = self.initial_cube_state.copy()
        self.all_moves.rewind_start()
        self.all_moves.reset()
        pos = self.all_moves.parse(code, pos, self.current_cube_state.dimension)
        self.do_fast_forward(to_pos=pos)
        
    def set_as_initial_state(self):
        self.initial_cube_state = self.current_cube_state.copy()
        self.all_moves.truncate_before()
        
    def invert_moves(self):
        self.current_cube_state = self.initial_cube_state.copy()
        self.all_moves.invert()
        pos = self.all_moves.current_place
        self.all_moves.rewind_start()
        self.do_fast_forward(to_pos=pos)