-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathField.h
139 lines (120 loc) · 4.26 KB
/
Field.h
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
//
// Created by botanic on 8/7/15.
//
#ifndef ICFP2015_FIELD_H
#define ICFP2015_FIELD_H
#include <json/json.h>
#include <vector>
#include <cstring>
#include <string>
#include "Actions.h"
#include "Logger.h"
namespace icfp2015 {
using std::vector;
using std::string;
// field
class Field {
vector<char> field; // original state
vector<char> curfield; // updated state
unsigned int wid;
unsigned int hei;
public:
Field(const Json::Value &root) {
wid = root["width"].asUInt();
hei = root["height"].asUInt();
field.resize(wid * hei);
Json::Value cells = root["filled"];
for (const Json::Value &dot:cells) {
int x = dot["x"].asInt();
int y = dot["y"].asInt();
field[x + y * wid] = '*';
}
curfield = field;
}
const unsigned width() { return wid; }
const unsigned height() { return hei; }
const long penalty() const {
long penalty = 0;
vector<int> lock;
vector<int> free;
for (int line = 0; line < hei; ++line) {
bool locked = true;
int straight = 0;
int closed = 0;
for (int col = 0; col < wid; ++col) {
if (locked ? (curfield[line * wid + col] != 0) : (curfield[line * wid + col] == 0)) {
++straight;
} else {
(locked ? lock : free).push_back(straight);
locked = !locked;
straight = 1;
}
if (line != 0 && !locked) { // upper neighbors for free spaces
int prevIdx = (line & 1) ? col : (col - 1);
if (prevIdx >= 0 && curfield[(line - 1) * wid + prevIdx] != 0)
++closed;
if (curfield[(line - 1) * wid + prevIdx + 1] != 0)
++closed;
}
}
(locked ? lock : free).push_back(straight);
penalty += (lock.size() + free.size() - 1) * 10; // each interval + 10
penalty += 100 * closed; // each closed space + 100
if (lock[0] != 0) penalty -= 20; // locked from right or left
if (lock.size() > free.size()) penalty -= 20;
if (lock.size() != 0) {
for (int sz:free) {
penalty += 50 * (wid - sz);
}
}
}
return penalty;
}
void reset() {
curfield = field;
}
void clr(int x, int y) {
curfield[wid * y + x] = 0;
}
void set(int x, int y, bool locked = false) {
curfield[wid * y + x] = locked ? '*' : 'F';
}
const char operator()(int x, int y) {
return curfield[wid * y + x];
}
int simplify() {
int removedLines = 0;
for (int i = 0; i < hei; ++i) {
bool allSet = true;
for (int j = 0; j < wid; ++j) {
allSet &= curfield[i * wid + j] == '*';
}
if (allSet) {
++removedLines;
if (i != 0) {
memmove(&curfield[wid], &curfield[0], i * wid);
} else {
memset(&curfield[0], 0, wid);
}
}
}
return removedLines;
}
const void print(const string &s, bool withPenalty = false) const {
if (withPenalty) {
glbLog() << "-----------------(" << penalty() << ") " << s.c_str() << endl;
} else {
glbLog() << "-----------------" << s.c_str() << endl;
}
for (int i = 0; i < hei; ++i) {
if (i & 1) glbLog() << ' ';
for (int j = 0; j < wid; ++j) {
glbLog() << (curfield[i * wid + j] ?: '.') << ' ';
}
glbLog() << endl;
}
glbLog() << "-----------------" << endl;
}
};
}
#endif //ICFP2015_FIELD_H