1 /***********************************************************************
2  *
3  * Copyright (C) 2007, 2008, 2010 Graeme Gott <graeme@gottcode.org>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  ***********************************************************************/
19 
20 #include "piece.h"
21 
22 #include "board.h"
23 
24 /*****************************************************************************/
25 
26 static const Cell types[][4] = {
27 	{ Cell(0,0), Cell(0,1), Cell(0,2), Cell(0,3) },
28 	{ Cell(0,0), Cell(0,1), Cell(1,1), Cell(1,2) },
29 	{ Cell(1,0), Cell(0,1), Cell(1,1), Cell(0,2) },
30 	{ Cell(0,0), Cell(0,1), Cell(1,1), Cell(0,2) },
31 	{ Cell(0,0), Cell(1,0), Cell(1,1), Cell(1,2) },
32 	{ Cell(0,0), Cell(1,0), Cell(0,1), Cell(0,2) },
33 	{ Cell(0,0), Cell(1,0), Cell(0,1), Cell(1,1) }
34 };
35 
36 /*****************************************************************************/
37 
Piece(int type,Board * board)38 Piece::Piece(int type, Board* board)
39 :	m_type(type),
40 	m_pivot(4,1),
41 	m_valid(false),
42 	m_board(board)
43 {
44 	Q_ASSERT(type > 0 && type < 8);
45 
46 	Cell position[4];
47 	cells(position, type);
48 	for (int i = 0; i < 4; ++i)
49 		position[i].x += 4;
50 
51 	if (updatePosition(position))
52 		m_valid = true;
53 }
54 
55 /*****************************************************************************/
56 
rotate()57 bool Piece::rotate()
58 {
59 	if (m_type == 7) {
60 		return true;
61 	}
62 
63 	Cell rotated[4];
64 	for (int i = 0; i < 4; ++i) {
65 		rotated[i].x = m_pivot.x - m_pivot.y + m_cells[i].y;
66 		rotated[i].y = m_pivot.x + m_pivot.y - m_cells[i].x;
67 		if (rotated[i].x > 9 || rotated[i].x < 0 || rotated[i].y > 19 || rotated[i].y < 0) {
68 			return false;
69 		}
70 	}
71 
72 	return updatePosition(rotated);
73 }
74 
75 /*****************************************************************************/
76 
drop()77 void Piece::drop()
78 {
79 	for (int i = 0; i < 20; ++i)
80 		moveDown();
81 }
82 
83 /*****************************************************************************/
84 
cells(Cell * cells,int type)85 void Piece::cells(Cell* cells, int type)
86 {
87 	Q_ASSERT(cells != 0);
88 	Q_ASSERT(type > 0 && type < 8);
89 
90 	const Cell* values = types[type - 1];
91 	for (int i = 0; i < 4; ++i)
92 		cells[i] = values[i];
93 }
94 
95 /*****************************************************************************/
96 
move(int x,int y)97 bool Piece::move(int x, int y)
98 {
99 	// Move cells
100 	Cell moved[4];
101 	for (int i = 0; i < 4; ++i) {
102 		moved[i].x = m_cells[i].x + x;
103 		moved[i].y = m_cells[i].y + y;
104 		if (moved[i].x > 9 || moved[i].x < 0 || moved[i].y > 19 || moved[i].y < 0)
105 			return false;
106 	}
107 
108 	bool success = updatePosition(moved);
109 	if (success) {
110 		m_pivot.x += x;
111 		m_pivot.y += y;
112 	}
113 	return success;
114 }
115 
116 /*****************************************************************************/
117 
updatePosition(const Cell * cells)118 bool Piece::updatePosition(const Cell* cells)
119 {
120 	// Check for collision of cells
121 	const Cell* cell = 0;
122 	for (int i = 0; i < 4; ++i) {
123 		cell = &cells[i];
124 		if (m_board->cell(cell->x, cell->y)) {
125 			return false;
126 		}
127 	}
128 
129 	// Move cells
130 	for (int i = 0; i < 4; ++i) {
131 		m_cells[i] = cells[i];
132 	}
133 
134 	return true;
135 }
136 
137 /*****************************************************************************/
138