Created
August 22, 2019 05:03
-
-
Save catupper/d60e7bd3cf3cb35e9b9494aae4dc59d2 to your computer and use it in GitHub Desktop.
pdes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int[][] open_field = new int[4][4]; | |
int[][] tmp_field = new int[4][4]; | |
int[] direction_x = {0, 1, 0, -1}; | |
int[] direction_y = {1, 0, -1, 0}; | |
int[] prob = {0, 9, 1}; | |
boolean AI_play = false; | |
int[][] num_color = { | |
{0, 0, 0}, | |
{238, 228, 218}, | |
{237, 224,200}, | |
{242,177,121}, | |
{245,149,99}, | |
{246,124,95}, | |
{246,94,59}, | |
{237,207,114}, | |
{237,204,97}, | |
{237,200,80}, | |
{237,197,63}, | |
{237,194,46}, | |
{138, 228, 218}, | |
{137, 224,200}, | |
{142,177,121}, | |
{145,149,99}, | |
{146,124,95}, | |
{146,94,59}, | |
{137,207,114}, | |
{137,204,97}, | |
{137,200,80}, | |
{137,197,63}, | |
{137,194,46}, | |
}; | |
int turn; | |
//0 -> Player | |
//1 -> generate new number | |
void copy_field(int[][] from, int[][] to) { | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
to[i][j] = from[i][j]; | |
} | |
} | |
} | |
void setup() { | |
size(640, 640); | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
open_field[i][j] = 0; | |
} | |
} | |
textSize(40); | |
turn = 1; | |
} | |
void draw_field() { | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
fill(num_color[open_field[i][j]][0], num_color[open_field[i][j]][1], num_color[open_field[i][j]][2]); | |
rect(i * 160, j * 160, 160, 160); | |
fill(0); | |
if (open_field[i][j] != 0) { | |
text(str(1 << open_field[i][j]), i*160, j * 160 + 80); | |
} | |
} | |
} | |
} | |
int calc_score(int[][] field, int x, int y, int val) { | |
int ret = -123456789; | |
if (field[x][y] != 0)return ret; | |
for (int i = 0; i < prob[val]; i++) { | |
ret = max(ret, int(random(0, 1000000))); | |
} | |
return ret; | |
} | |
void gen_num(int[][] field) { | |
int nx = 0, ny = 0, val = 1, max_score = -123456789; | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
for (int v = 1; v <= 2; v++) { | |
int new_score = calc_score(field, i, j, v); | |
if (new_score > max_score) { | |
max_score = new_score; | |
nx = i; | |
ny = j; | |
val = v; | |
} | |
} | |
} | |
} | |
field[nx][ny] = val; | |
} | |
boolean game_over(int[][] field) { | |
if (valid_move(field, -1, 0))return false; | |
if (valid_move(field, 1, 0))return false; | |
if (valid_move(field, 0, -1))return false; | |
if (valid_move(field, 0, 1))return false; | |
return true; | |
} | |
int field_score(int[][] field) { | |
int score = 0; | |
for (int i = 0; i < 4; i++) | |
for (int j = 0; j < 4; j++) | |
if (field[i][j] != 0) | |
score += 1 << field[i][j]; | |
return score; | |
} | |
int calc_AI_score(int[][] field) { | |
return int(random(0, 10000)); | |
} | |
boolean valid_move(int[][] field, int dx, int dy) { | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
if (field[i][j] != 0 && on_field(i + dx, j + dy) && (field[i+dx][j+dy] == 0 || field[i+dx][j+dy] == field[i][j]))return true; | |
} | |
} | |
return false; | |
} | |
void AI(int[][] field) { | |
int nx = 0, ny = 0, max_score = -123456789, tmp_score; | |
int[][] tmp_field = new int[4][4]; | |
for(int i = 0;i < 4;i++){ | |
int dx = direction_x[i]; | |
int dy = direction_y[i]; | |
if (valid_move(field, dx, dy)) { | |
copy_field(field, tmp_field); | |
move(tmp_field, dx, dy); | |
tmp_score = calc_AI_score(tmp_field); | |
if (tmp_score > max_score) { | |
max_score = tmp_score; | |
nx = dx; | |
ny = dy; | |
} | |
} | |
} | |
move(field, nx, ny); | |
} | |
void draw() { | |
draw_field(); | |
if (field_score(open_field)!=0&& game_over(open_field)) { | |
println(field_score(open_field)); | |
} else if (turn == 1) { | |
gen_num(open_field); | |
turn = 1 - turn; | |
} else if (turn == 0 && AI_play) { | |
AI(open_field); | |
turn = 1 - turn; | |
} | |
} | |
boolean on_field(int x, int y) { | |
return 0 <= x && x < 4 && 0 <= y && y < 4; | |
} | |
void push(int[][] field, int dx, int dy) { | |
for (int trial = 0; trial < 4; trial++) { | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
int nx = i + dx; | |
int ny = j + dy; | |
if (!on_field(nx, ny))continue; | |
if (field[nx][ny] != 0)continue; | |
field[nx][ny] = field[i][j]; | |
field[i][j] = 0; | |
} | |
} | |
} | |
} | |
void move(int[][] field, int dx, int dy) { | |
push(field, dx, dy); | |
for (int i = 0; i < 4; i++) { | |
for (int j = 0; j < 4; j++) { | |
if (field[i][j] == 0)continue; | |
int nx = i, ny = j; | |
while (on_field(nx+dx, ny+dy) && field[nx][ny] == field[nx+dx][ny+dy]) { | |
nx += dx; | |
ny += dy; | |
} | |
if (nx == i && ny == j)continue; | |
field[nx][ny]++; | |
field[nx][ny] *= -1; | |
field[nx-dx][ny-dy] = 0; | |
} | |
} | |
for (int i = 0; i < 4; i++) | |
for (int j = 0; j < 4; j++) | |
if (field[i][j] < 0) | |
field[i][j] *= -1; | |
push(field, dx, dy); | |
} | |
void keyPressed() { | |
if (AI_play)return; | |
if (turn != 0)return; | |
if (key == CODED) { | |
if (keyCode == UP && valid_move(open_field, 0, -1)) { | |
move(open_field, 0, -1); | |
turn = 1 - turn; | |
} else if (keyCode == DOWN && valid_move(open_field, 0, 1)) { | |
move(open_field, 0, 1); | |
turn = 1 - turn; | |
} else if (keyCode == LEFT && valid_move(open_field, -1, 0)) { | |
move(open_field, -1, 0); | |
turn = 1 - turn; | |
} else if (keyCode == RIGHT && valid_move(open_field, 1, 0)) { | |
move(open_field, 1, 0); | |
turn = 1 - turn; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
int[][] open_field = new int[8][8]; | |
int[][] tmp_field = new int[8][8]; | |
int turn; | |
int[] token_color = {0, 0, 255}; | |
int[] direction_x = {0, 1, 1, 1, 0, -1, -1, -1}; | |
int[] direction_y = {1, 1, 0, -1, -1, -1, 0, 1}; | |
void copy_field(int[][] from, int[][] to) { | |
for (int i = 0; i < 8; i++) { | |
for (int j = 0; j < 8; j++) { | |
to[i][j] = from[i][j]; | |
} | |
} | |
} | |
void setup() { | |
size(640, 750); | |
for (int i = 0; i < 8; i++) { | |
for (int j = 0; j < 8; j++) { | |
open_field[i][j] = 0; | |
} | |
} | |
open_field[3][3] = 1; | |
open_field[3][4] = 2; | |
open_field[4][3] = 2; | |
open_field[4][4] = 1; | |
turn = 1; | |
} | |
void draw_field() { | |
background(0, 255, 0); | |
for (int i = 0; i <= 8; i++) { | |
line(80 * i, 0, 80 * i, 640); | |
line(0, 80 * i, 640, 80 * i); | |
} | |
for (int i = 0; i < 8; i++) { | |
for (int j = 0; j < 8; j++) { | |
if (open_field[i][j] != 0) { | |
fill(token_color[open_field[i][j]]); | |
ellipse(i * 80 + 40, j * 80 + 40, 70, 70); | |
} | |
} | |
} | |
fill(token_color[turn]); | |
ellipse(320, 680, 70, 70); | |
} | |
boolean on_field(int x, int y) { | |
return 0 <= x && x < 8 && 0 <= y && y < 8; | |
} | |
boolean available(int[][] field, int x, int y, int turn) { | |
if (field[x][y] != 0)return false; | |
for (int i = 0; i < 8; i++) { | |
int dx = direction_x[i]; | |
int dy = direction_y[i]; | |
int edgex = x + dx; | |
int edgey = y + dy; | |
int flip_cnt = 0; | |
while (on_field(edgex, edgey) && field[edgex][edgey] == 3 - turn) { | |
edgex += dx; | |
edgey += dy; | |
flip_cnt += 1; | |
} | |
if (on_field(edgex, edgey) && field[edgex][edgey] == turn && flip_cnt > 0)return true; | |
} | |
return false; | |
} | |
void flip(int[][] field, int x, int y, int turn) { | |
field[x][y] = turn; | |
for (int i = 0; i < 8; i++) { | |
int dx = direction_x[i]; | |
int dy = direction_y[i]; | |
int edgex = x + dx; | |
int edgey = y + dy; | |
while (on_field(edgex, edgey) && field[edgex][edgey] == 3 - turn) { | |
edgex += dx; | |
edgey += dy; | |
} | |
if (on_field(edgex, edgey) && field[edgex][edgey] == turn) { | |
while (edgex != x || edgey != y) { | |
field[edgex][edgey] = turn; | |
edgex -= dx; | |
edgey -= dy; | |
} | |
} | |
} | |
} | |
boolean pass(int[][] field, int turn) { | |
for (int i = 0; i < 8; i++) { | |
for (int j = 0; j < 8; j++) { | |
if (available(field, i, j, turn))return false; | |
} | |
} | |
return true; | |
} | |
int[] result(int[][] field) { | |
int[] cnt = {0, 0, 0}; | |
for (int i = 0; i < 8; i++) { | |
for (int j = 0; j < 8; j++) { | |
cnt[field[i][j]] += 1; | |
} | |
} | |
return cnt; | |
} | |
int calc_score(int[][] field, int x, int y, int turn){ | |
if(!available(field, x, y, turn))return -123456789; | |
return int(random(0, 1000)); | |
} | |
void AI(int[][] field, int turn) { | |
int nx = 0, ny = 0, max_score = -123456789; | |
for (int i = 0; i < 8; i++) { | |
for (int j = 0; j < 8; j++) { | |
int new_score = calc_score(field, i, j, turn); | |
if (new_score > max_score) { | |
max_score = new_score; | |
nx = i; | |
ny = j; | |
} | |
} | |
} | |
flip(open_field, nx, ny, turn); | |
} | |
void draw() { | |
draw_field(); | |
if(pass(open_field,turn)){ | |
turn = 3 - turn; | |
if(pass(open_field, turn)){ | |
println(result(open_field)); | |
turn = 3 - turn; | |
return; | |
} | |
} | |
if (turn == 2) { | |
AI(open_field, turn); | |
turn = 3 - turn; | |
} | |
} | |
void mousePressed() { | |
if (turn != 1)return; | |
int x = mouseX / 80; | |
int y = mouseY / 80; | |
if (available(open_field, x, y, turn)) { | |
flip(open_field, x, y, turn); | |
turn = 3 - turn; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment