-
Notifications
You must be signed in to change notification settings - Fork 0
/
difficulty.cc
107 lines (83 loc) · 2.59 KB
/
difficulty.cc
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
#include "difficulty.h"
#include "grid.h"
#include <vector>
#include <iostream>
#include <stdexcept>
#include <cstdlib>
using namespace std;
// ctor
Difficulty::Difficulty(vector <vector <Cell>> * bd, std::string loadPath):
board{bd}, loadPath{loadPath}{}
// dtor
Difficulty::Difficulty(){}
bool Difficulty::validPosition(Block b){
std::vector<Cell> area = b.getArea();
for(int i=0; i<4; ++i){
int row = area[i].row;
int col = area[i].col;
if (row < 0 || row >= HEIGHT || col < 0 || col >= WIDTH ||
((*board)[row][col].content != Content::Empty &&
!(*board)[row][col].temp))
return false;
} return true;
}
// MAGIC: DO NOT TOUCH!!!
Block Difficulty::cwRotate(Block b){
int width = b.getWidth();
Block rotated = b;
std::vector<Cell> oldArea = b.getArea();
std::vector<Cell> newArea;
for(int i=0; i<4; ++i)
// Following 3 lines is the key that makes the rotation work!
// First we find the smartest rectangle that contains the block;
// then rotate the rectangle without cells that have not be covered
newArea.emplace_back(Cell{oldArea[i].content,
(b.getRow() - width + 1) + (oldArea[i].col - b.getCol()),
b.getCol() + (b.getRow() - oldArea[i].row)});
rotated.setArea(newArea);
rotated.setRotation((b.getRotation()+1) % 4);
if(validPosition(rotated)) return rotated;
return b;
}
Block Difficulty::moveByWeight(Block b){
Block moved = b;
moved.setRow(b.getRow()+b.getWeight());
if(validPosition(moved)) return moved;
return b;
}
Block Difficulty::rotateClock(Block b){
return moveByWeight(cwRotate(b));
}
Block Difficulty::rotateCounter(Block b){
return moveByWeight(cwRotate(cwRotate(cwRotate(b))));
}
Block Difficulty::moveDown(Block b){
Block moved = b;
moved.setRow(b.getRow()+1);
if(validPosition(moved)) return moveByWeight(moved);
return moveByWeight(b);
}
Block Difficulty::moveLeft(Block b){
Block moved = b;
moved.setCol(b.getCol()-1);
if(validPosition(moved)) return moveByWeight(moved);
return moveByWeight(b);
}
Block Difficulty::moveRight(Block b){
Block moved = b;
moved.setCol(b.getCol()+1);
if(validPosition(moved)) return moveByWeight(moved);
return moveByWeight(b);
}
Block Difficulty::drop(Block b){
Block moved = moveDown(b);
for(int prevRow = b.getRow(), currRow = moved.getRow();
prevRow != currRow;){
prevRow = currRow;
moved = moveDown(moved);
currRow = moved.getRow();
}
return moveByWeight(moved);
}
void Difficulty::implementPenalty(){}
void update(std::vector <std::vector <Cell*>> & bd);