// SPDX-License-Identifier: MIT
// SPDX-FileCopyrightText: © 2014 Maurits van der Schee

/* Console version of the game "2048" for GNU/Linux */

#include <cli.h>
#include <command.h>
#include <rand.h>
#include <vsprintf.h>
#include <linux/delay.h>

#define SIZE 4
static uint score;

static void getColor(uint value, char *color, size_t length)
{
	u8 original[] = {
		8, 255, 1, 255, 2, 255, 3, 255,
		4, 255, 5, 255, 6, 255, 7, 255,
		9, 0, 10, 0, 11, 0, 12, 0, 13,
		0, 14, 0, 255, 0, 255, 0};
	u8 *scheme = original;
	u8 *background = scheme + 0;
	u8 *foreground = scheme + 1;

	if (value > 0) {
		while (value >>= 1) {
			if (background + 2 < scheme + sizeof(original)) {
				background += 2;
				foreground += 2;
			}
		}
	}
	snprintf(color, length, "\033[38;5;%d;48;5;%dm", *foreground,
		 *background);
}

static void drawBoard(u16 board[SIZE][SIZE])
{
	int x, y;
	char color[40], reset[] = "\033[0m";

	printf("\033[H");
	printf("2048.c %17d pts\n\n", score);

	for (y = 0; y < SIZE; y++) {
		for (x = 0; x < SIZE; x++) {
			getColor(board[x][y], color, 40);
			printf("%s", color);
			printf("       ");
			printf("%s", reset);
		}
		printf("\n");
		for (x = 0; x < SIZE; x++) {
			getColor(board[x][y], color, 40);
			printf("%s", color);
			if (board[x][y] != 0) {
				char s[8];
				s8 t;

				snprintf(s, 8, "%u", board[x][y]);
				t = 7 - strlen(s);
				printf("%*s%s%*s", t - t / 2, "", s, t / 2, "");
			} else {
				printf("   ·   ");
			}
			printf("%s", reset);
		}
		printf("\n");
		for (x = 0; x < SIZE; x++) {
			getColor(board[x][y], color, 40);
			printf("%s", color);
			printf("       ");
			printf("%s", reset);
		}
		printf("\n");
	}
	printf("\n");
	printf("        ←, ↑, →, ↓ or q        \n");
	printf("\033[A");
}

static int8_t findTarget(u16 array[SIZE], int x, int stop)
{
	int t;

	/* if the position is already on the first, don't evaluate */
	if (x == 0)
		return x;
	for (t = x - 1; t >= 0; t--) {
		if (array[t]) {
			if (array[t] != array[x]) {
				/* merge is not possible, take next position */
				return t + 1;
			}
			return t;
		}

		/* we should not slide further, return this one */
		if (t == stop)
			return t;
	}
	/* we did not find a */
	return x;
}

static bool slideArray(u16 array[SIZE])
{
	bool success = false;
	int x, t, stop = 0;

	for (x = 0; x < SIZE; x++) {
		if (array[x] != 0) {
			t = findTarget(array, x, stop);
			/*
			 * if target is not original position, then move or
			 * merge
			 */
			if (t != x) {
				/*
				 * if target is not zero, set stop to avoid
				 * double merge
				 */
				if (array[t]) {
					score += array[t] + array[x];
					stop = t + 1;
				}
				array[t] += array[x];
				array[x] = 0;
				success = true;
			}
		}
	}
	return success;
}

static void rotateBoard(u16 board[SIZE][SIZE])
{
	s8 i, j, n = SIZE;
	int tmp;

	for (i = 0; i < n / 2; i++) {
		for (j = i; j < n - i - 1; j++) {
			tmp = board[i][j];
			board[i][j] = board[j][n - i - 1];
			board[j][n - i - 1] = board[n - i - 1][n - j - 1];
			board[n - i - 1][n - j - 1] = board[n - j - 1][i];
			board[n - j - 1][i] = tmp;
		}
	}
}

static bool moveUp(u16 board[SIZE][SIZE])
{
	bool success = false;
	int x;

	for (x = 0; x < SIZE; x++)
		success |= slideArray(board[x]);

	return success;
}

static bool moveLeft(u16 board[SIZE][SIZE])
{
	bool success;

	rotateBoard(board);
	success = moveUp(board);
	rotateBoard(board);
	rotateBoard(board);
	rotateBoard(board);
	return success;
}

static bool moveDown(u16 board[SIZE][SIZE])
{
	bool success;

	rotateBoard(board);
	rotateBoard(board);
	success = moveUp(board);
	rotateBoard(board);
	rotateBoard(board);
	return success;
}

static bool moveRight(u16 board[SIZE][SIZE])
{
	bool success;

	rotateBoard(board);
	rotateBoard(board);
	rotateBoard(board);
	success = moveUp(board);
	rotateBoard(board);
	return success;
}

static bool findPairDown(u16 board[SIZE][SIZE])
{
	bool success = false;
	int x, y;

	for (x = 0; x < SIZE; x++) {
		for (y = 0; y < SIZE - 1; y++) {
			if (board[x][y] == board[x][y + 1])
				return true;
		}
	}

	return success;
}

static int16_t countEmpty(u16 board[SIZE][SIZE])
{
	int x, y;
	int count = 0;

	for (x = 0; x < SIZE; x++) {
		for (y = 0; y < SIZE; y++) {
			if (board[x][y] == 0)
				count++;
		}
	}
	return count;
}

static bool gameEnded(u16 board[SIZE][SIZE])
{
	bool ended = true;

	if (countEmpty(board) > 0)
		return false;
	if (findPairDown(board))
		return false;
	rotateBoard(board);
	if (findPairDown(board))
		ended = false;
	rotateBoard(board);
	rotateBoard(board);
	rotateBoard(board);

	return ended;
}

static void addRandom(u16 board[SIZE][SIZE])
{
	int x, y;
	int r, len = 0;
	u16 n, list[SIZE * SIZE][2];

	for (x = 0; x < SIZE; x++) {
		for (y = 0; y < SIZE; y++) {
			if (board[x][y] == 0) {
				list[len][0] = x;
				list[len][1] = y;
				len++;
			}
		}
	}

	if (len > 0) {
		r = rand() % len;
		x = list[r][0];
		y = list[r][1];
		n = ((rand() % 10) / 9 + 1) * 2;
		board[x][y] = n;
	}
}

static int test(void)
{
	u16 array[SIZE];
	u16 data[] = {
		0, 0, 0, 2,	2, 0, 0, 0,
		0, 0, 2, 2,	4, 0, 0, 0,
		0, 2, 0, 2,	4, 0, 0, 0,
		2, 0, 0, 2,	4, 0, 0, 0,
		2, 0, 2, 0,	4, 0, 0, 0,
		2, 2, 2, 0,	4, 2, 0, 0,
		2, 0, 2, 2,	4, 2, 0, 0,
		2, 2, 0, 2,	4, 2, 0, 0,
		2, 2, 2, 2,	4, 4, 0, 0,
		4, 4, 2, 2,	8, 4, 0, 0,
		2, 2, 4, 4,	4, 8, 0, 0,
		8, 0, 2, 2,	8, 4, 0, 0,
		4, 0, 2, 2,	4, 4, 0, 0
	};
	u16 *in, *out;
	u16 t, tests;
	int i;
	bool success = true;

	tests = (sizeof(data) / sizeof(data[0])) / (2 * SIZE);
	for (t = 0; t < tests; t++) {
		in = data + t * 2 * SIZE;
		out = in + SIZE;
		for (i = 0; i < SIZE; i++)
			array[i] = in[i];
		slideArray(array);
		for (i = 0; i < SIZE; i++) {
			if (array[i] != out[i])
				success = false;
		}
		if (!success) {
			for (i = 0; i < SIZE; i++)
				printf("%d ", in[i]);
			printf(" = > ");
			for (i = 0; i < SIZE; i++)
				printf("%d ", array[i]);
			printf("expected ");
			for (i = 0; i < SIZE; i++)
				printf("%d ", in[i]);
			printf(" = > ");
			for (i = 0; i < SIZE; i++)
				printf("%d ", out[i]);
			printf("\n");
			break;
		}
	}
	if (success)
		printf("All %u tests executed successfully\n", tests);

	return !success;
}

static int do_2048(struct cmd_tbl *cmdtp, int flag, int argc,
		   char *const argv[])
{
	struct cli_ch_state cch_s, *cch = &cch_s;
	u16 board[SIZE][SIZE];
	bool success;

	if (argc == 2 && strcmp(argv[1], "test") == 0)
		return test();

	score = 0;

	printf("\033[?25l\033[2J\033[H");

	memset(board, 0, sizeof(board));
	addRandom(board);
	addRandom(board);
	drawBoard(board);
	cli_ch_init(cch);
	while (true) {
		int c;

		c = cli_ch_process(cch, 0);
		if (!c) {
			c = getchar();
			c = cli_ch_process(cch, c);
		}
		switch (c) {
		case CTL_CH('b'): /* left arrow */
			success = moveLeft(board);
			break;
		case CTL_CH('f'): /* right arrow */
			success = moveRight(board);
			break;
		case CTL_CH('p'):/* up arrow */
			success = moveUp(board);
			break;
		case CTL_CH('n'): /* down arrow */
			success = moveDown(board);
			break;
		default:
			success = false;
		}
		if (success) {
			drawBoard(board);
			mdelay(150);
			addRandom(board);
			drawBoard(board);
			if (gameEnded(board)) {
				printf("         GAME OVER          \n");
				break;
			}
		}
		if (c == 'q') {
			printf("            QUIT            \n");
			break;
		}
	}

	printf("\033[?25h");

	return 0;
}

U_BOOT_CMD(
	2048,	2,	1,	do_2048,
	"The 2048 game",
	"Use your arrow keys to move the tiles. When two tiles with "
	"the same number touch, they merge into one!"
);
