From d1dd8eaad347c81e4db04e63593b41d6bd939b56 Mon Sep 17 00:00:00 2001
From: Zefan Xu <benjamin.xzf@gmail.com>
Date: Wed, 11 May 2016 08:37:27 -0500
Subject: [PATCH] 2048 minor bugs

---
 student-distrib/2048.c             |  51 +++
 student-distrib/2048.h             |   7 +
 student-distrib/game.c             | 516 +++++++++++++++++++++++++++++
 student-distrib/game.h             |  41 +++
 student-distrib/keyboard_handler.c | 348 +++++++++----------
 student-distrib/malloc.c           |   4 +-
 6 files changed, 793 insertions(+), 174 deletions(-)
 create mode 100644 student-distrib/2048.c
 create mode 100644 student-distrib/2048.h
 create mode 100644 student-distrib/game.c
 create mode 100644 student-distrib/game.h

diff --git a/student-distrib/2048.c b/student-distrib/2048.c
new file mode 100644
index 0000000..1aad8f0
--- /dev/null
+++ b/student-distrib/2048.c
@@ -0,0 +1,51 @@
+#include "game.h"
+#include "malloc.h"
+#include "terminal.h"
+#include "keyboard_handler.h"
+
+int start_2048()
+{
+	sti();
+	int rows, cols;
+	char key = ' ';
+	char buf[200];
+	char garbage[2];
+	clear();
+	printf("2048: Enter dimensions (rowscolumns), for example: 4 4\n");
+	printf("max 9 rows and 9 columns:\n");
+	while (1) {
+		terminal_read(0, buf, 10);
+		if (buf[0] > 48 && buf[0] < 58 && buf[2] > 48 && buf[2] < 58) {
+			//printf("%c %c\n", buf[0], buf[2]);
+			rows = buf[0] - 48;
+			cols = buf[2] - 48;
+			break;
+		}
+		else
+			printf("please enter dimensions in the correct form");
+	}
+	//printf("game has been made\n");
+
+	game * cur_game = make_game(rows, cols); //make new game entity called cur_game and insert the first random tile
+	//printf("current game: %d\n", (uint32_t)cur_game);
+	if ( cur_game == NULL ) {
+		printf("Bad game pointer\n");
+		return 2;
+	}
+	//printf("%lf\n",((double)malloc_usable_size(cur_game->cells))/sizeof(int));
+	//printf("before rand_new tile\n");
+	rand_new_tile(cur_game);
+	//printf("rand_new_tile\n");
+	print_game(cur_game);
+	//printf("print_game\n");
+	char c;
+	do {
+		terminal_read(0, buf, 10);
+		c = buf[0]; //get character input; does not require a return keypress after input.
+
+	} while ( process_turn(c, cur_game ) == 1); //call process_turn and check if successful
+
+
+	printf("\n391OS>");
+	return 0;
+}
diff --git a/student-distrib/2048.h b/student-distrib/2048.h
new file mode 100644
index 0000000..f526dee
--- /dev/null
+++ b/student-distrib/2048.h
@@ -0,0 +1,7 @@
+#ifndef _2048_H
+#define _2048_H
+
+int start_2048();
+
+
+#endif
diff --git a/student-distrib/game.c b/student-distrib/game.c
new file mode 100644
index 0000000..9bd2aa7
--- /dev/null
+++ b/student-distrib/game.c
@@ -0,0 +1,516 @@
+/*
+Zefan Xu
+ECE 220 MP7
+
+This file contains functions that helps running the algorithm of 2048.
+Data associated with each game is stored in struct game, which consists
+of number of rows, columns and score, as well as a dynamic array of cells.
+
+make_game allocate dynamic memory needed by this struct and initialize the
+default value of each cell to -1
+
+destroy_game frees all the memory associated with a particular game struct
+
+get_cell takes a pair of 2D index and return the pointer to that cell
+
+move_w moves up and merges the cells based on the rules of 2048
+
+move_a moves left and merges the cells based on the rules of 2048
+
+move_d moves right and merges the cells based on the rules of 2048
+
+move_s moves down and merges the cells based on the rules of 2048
+
+legal_move_check returns 1 if there are still legal moves available,
+otherwise returns 0
+
+remake_game first frees memory associated with the old game, and then
+allocate memory and initialized default cell values for the new game
+
+I don't know what other functions do, because I did't write them,
+nor did I read them, and I don't care.
+*/
+#include "game.h"
+
+int index_random = 0;
+
+game * make_game(int rows, int cols)
+{
+	int i;
+	//printf("make_game\n");
+	game * newgame = malloc(sizeof(game)); // allocate for game struct first
+	//printf("malloc\n");
+	//printf("new game: %x\n", (uint32_t)newgame);
+	if (newgame == NULL) return NULL;
+	newgame->rows = rows;
+	newgame->cols = cols; // initialize values
+	newgame->cells = malloc(rows * cols * sizeof(int)); // allocate dynamic array for cells
+	//printf("cells memory: %x\n", (uint32_t)newgame->cells);
+	if (newgame->cells == NULL) return NULL;
+	for (i = 0; i < rows * cols; i++) {
+		//printf("each cell: %x\n", (uint32_t)(newgame->cells + i));
+		*(newgame->cells + i) = -1; //initialize the dynamic array
+	}
+	//printf("finished initialization\n");
+	newgame->score = 0;
+	return newgame; // return the pointer to the new game
+}
+
+
+
+void destroy_game(game * cur_game)
+{
+	free(cur_game->cells); // free cells first
+	free(cur_game); // free the game struct
+	return;
+}
+
+cell * get_cell(game * cur_game, int row, int col)
+{
+	if (row < 0 || row >= cur_game->rows || col < 0 || col >= cur_game->cols) return NULL;
+	return (cur_game->cells + row * (cur_game->cols) + col); // convert the 2D index into 1D and return the pointer
+}
+
+int move_w(game * cur_game)
+{
+	int i, r, c;
+	int rows = cur_game->rows;
+	int cols = cur_game->cols;
+	int moved = 0;
+	//swap up all the cell
+	for (c = 0; c < cols; c++) {
+		for (i = 0; i < rows - 1; i++) {
+			for (r = 0; r < rows - 1; r++) {
+				if (*get_cell(cur_game, r, c) == -1) {
+					if (*get_cell(cur_game, r + 1, c) != -1) {
+						*get_cell(cur_game, r, c) = *get_cell(cur_game, r + 1, c);
+						*get_cell(cur_game, r + 1, c) = -1;
+						moved = 1; // record a move
+					}
+				}
+			}
+		}
+	}
+	//merge
+	for (c = 0; c < cols; c++) {
+		for (r = 0; r < rows - 1; r++) {
+			if (*get_cell(cur_game, r, c) == *get_cell(cur_game, r + 1, c) && *get_cell(cur_game, r, c) != -1) {
+				*get_cell(cur_game, r, c) = *get_cell(cur_game, r, c) * 2;
+				*get_cell(cur_game, r + 1, c) = -1;
+				cur_game->score += *get_cell(cur_game, r, c); // increment the score
+				moved = 1; // record a move
+			}
+		}
+	}
+	//swap up again after the merge
+	if (moved) {
+		for (c = 0; c < cols; c++) {
+			for (i = 0; i < rows - 1; i++) {
+				for (r = 0; r < rows - 1; r++) {
+					if (*get_cell(cur_game, r, c) == -1) {
+						if (*get_cell(cur_game, r + 1, c) != -1) {
+							*get_cell(cur_game, r, c) = *get_cell(cur_game, r + 1, c);
+							*get_cell(cur_game, r + 1, c) = -1;
+							moved = 1;
+						}
+					}
+				}
+			}
+		}
+	}
+	if (moved)
+		return 1;
+	else return 0;
+};
+
+int move_s(game * cur_game) //slide down
+{
+
+	int i, r, c;
+	int rows = cur_game->rows;
+	int cols = cur_game->cols;
+	int moved = 0;
+	//swap down all the cells
+	for (c = 0; c < cols; c++) {
+		for (i = 0; i < rows - 1; i++) {
+			for (r = 0; r < rows - 1; r++) {
+				if (*get_cell(cur_game, r + 1, c) == -1) {
+					if (*get_cell(cur_game, r, c) != -1) {
+						*get_cell(cur_game, r + 1, c) = *get_cell(cur_game, r, c);
+						*get_cell(cur_game, r, c) = -1;
+						moved = 1; //record the move
+					}
+				}
+			}
+		}
+	}
+	//merge
+	for (c = 0; c < cols; c++) {
+		for (r = rows - 2; r > -1; r--) {
+			if (*get_cell(cur_game, r, c) == *get_cell(cur_game, r + 1, c) && *get_cell(cur_game, r, c) != -1) {
+				*get_cell(cur_game, r + 1, c) = *get_cell(cur_game, r, c) * 2;
+				*get_cell(cur_game, r, c) = -1;
+				cur_game->score += *get_cell(cur_game, r + 1, c); // increment the score
+				moved = 1; // record a move
+			}
+		}
+	}
+	//swap down again
+	if (moved) {
+		for (c = 0; c < cols; c++) {
+			for (i = 0; i < rows - 1; i++) {
+				for (r = 0; r < rows - 1; r++) {
+					if (*get_cell(cur_game, r + 1, c) == -1) {
+						if (*get_cell(cur_game, r, c) != -1) {
+							*get_cell(cur_game, r + 1, c) = *get_cell(cur_game, r, c);
+							*get_cell(cur_game, r, c) = -1;
+						}
+					}
+				}
+			}
+		}
+	}
+	if (moved)
+		return 1;
+	else return 0;
+};
+
+int move_a(game * cur_game) //slide left
+{
+	int i, r, c;
+	int rows = cur_game->rows;
+	int cols = cur_game->cols;
+	int temp;
+	int moved = 0;
+	//swap left all the cells
+	for (r = 0; r < rows; r++) {
+		for (i = 0; i < cols - 1; i++) {
+			for (c = 0; c < cols - 1; c++) {
+				if (*get_cell(cur_game, r, c) == -1) {
+					if (*get_cell(cur_game, r, c + 1) != -1) {
+						temp = *get_cell(cur_game, r, c);
+						*get_cell(cur_game, r, c) = *get_cell(cur_game, r, c + 1);
+						*get_cell(cur_game, r, c + 1) = temp;
+						moved = 1; // record a move
+					}
+				}
+			}
+		}
+	}
+	//merge
+	for (r = 0; r < rows; r++) {
+		for (c = 0; c < cols - 1; c++) {
+			if (*get_cell(cur_game, r, c) == *get_cell(cur_game, r, c + 1) && *get_cell(cur_game, r, c) != -1) {
+				*get_cell(cur_game, r, c) = *get_cell(cur_game, r, c) * 2;
+				*get_cell(cur_game, r, c + 1) = -1;
+				cur_game->score += *get_cell(cur_game, r, c); // increment the score
+				moved = 1; // record the move
+			}
+		}
+	}
+	//swap again
+	if (moved) {
+		for (r = 0; r < rows; r++) {
+			for (i = 0; i < cols - 1; i++) {
+				for (c = 0; c < cols - 1; c++) {
+					if (*get_cell(cur_game, r, c) == -1) {
+						if (*get_cell(cur_game, r, c + 1) != -1) {
+							temp = *get_cell(cur_game, r, c);
+							*get_cell(cur_game, r, c) = *get_cell(cur_game, r, c + 1);
+							*get_cell(cur_game, r, c + 1) = temp;
+						}
+					}
+				}
+			}
+		}
+	}
+	if (moved)
+		return 1;
+	else return 0;
+};
+
+int move_d(game * cur_game) { //slide to the right
+	int i, r, c;
+	int rows = cur_game->rows;
+	int cols = cur_game->cols;
+	int temp;
+	int moved = 0;
+	//swap right all the cells
+	for (r = 0; r < rows; r++) {
+		for (i = 0; i < cols - 1; i++) {
+			for (c = 0; c < cols - 1; c++) {
+				if (*get_cell(cur_game, r, c + 1) == -1) {
+					if (*get_cell(cur_game, r, c) != -1) {
+						temp = *get_cell(cur_game, r, c);
+						*get_cell(cur_game, r, c) = *get_cell(cur_game, r, c + 1);
+						*get_cell(cur_game, r, c + 1) = temp;
+						moved = 1; // record a move
+					}
+				}
+			}
+		}
+	}
+	//merge
+	for (r = 0; r < rows; r++) {
+		for (c = cols - 2; c > -1; c--) {
+			if (*get_cell(cur_game, r, c) == *get_cell(cur_game, r, c + 1) && *get_cell(cur_game, r, c + 1) != -1) {
+				*get_cell(cur_game, r, c + 1) = *get_cell(cur_game, r, c + 1) * 2;
+				*get_cell(cur_game, r, c) = -1;
+				cur_game->score += *get_cell(cur_game, r, c + 1); // increment the score
+				moved = 1; // record a move
+			}
+		}
+	}
+	//swap again
+	if (moved) {
+		for (r = 0; r < rows; r++) {
+			for (i = 0; i < cols - 1; i++) {
+				for (c = 0; c < cols - 1; c++) {
+					if (*get_cell(cur_game, r, c + 1) == -1) {
+						if (*get_cell(cur_game, r, c) != -1) {
+							temp = *get_cell(cur_game, r, c);
+							*get_cell(cur_game, r, c) = *get_cell(cur_game, r, c + 1);
+							*get_cell(cur_game, r, c + 1) = temp;
+						}
+					}
+				}
+			}
+		}
+	}
+	if (moved)
+		return 1;
+	else return 0;
+};
+
+int legal_move_check(game * cur_game)
+{
+	int rows = cur_game->rows; int cols = cur_game->cols;
+	int i, r, c;
+	//if any -1 exists, possible legal move exists
+	for (i = 0; i < rows * cols; i++) {
+		if (*(cur_game->cells + i) == -1) return 1;
+	}
+	//check available merge in horizontal direction
+	for (c = 0; c < cols; c++) {
+		for (r = 0; r < rows - 1; r++) {
+			if (*get_cell(cur_game, r, c) == *get_cell(cur_game, r + 1, c)) return 1;
+		}
+	}
+	//check available merge in vertical direction
+	for (r = 0; r < rows; r++) {
+		for (c = 0; c < cols - 1; c++) {
+			if (*get_cell(cur_game, r, c) == *get_cell(cur_game, r, c + 1)) return 1;
+		}
+	}
+	//printf("illegal move\n");
+	return 0;
+}
+
+
+void remake_game(game ** _cur_game_ptr, int new_rows, int new_cols)
+{
+	//clear the memory
+	destroy_game(* _cur_game_ptr);
+	//make a new one
+	*_cur_game_ptr = make_game(new_rows, new_cols);
+	return;
+}
+
+/*! code below is provided and should not be changed */
+
+void rand_new_tile(game * cur_game)
+/*! insert a new tile into a random empty cell. First call rand()%(rows*cols) to get a random value between 0 and (rows*cols)-1.
+*/
+{
+
+	cell * cell_ptr;
+	cell_ptr = 	cur_game->cells;
+
+	if (cell_ptr == NULL) {
+		printf("Bad Cell Pointer.\n");
+		//exit(0);
+	}
+
+
+	//check for an empty cell
+	int emptycheck = 0;
+	int i;
+
+	for (i = 0; i < ((cur_game->rows) * (cur_game->cols)); i++) {
+		if ((*cell_ptr) == -1) {
+			emptycheck = 1;
+			break;
+		}
+		cell_ptr += 1;
+	}
+	if (emptycheck == 0) {
+		printf("Error: Trying to insert into no a board with no empty cell. The function rand_new_tile() should only be called after tiles have succesfully moved, meaning there should be at least 1 open spot.\n");
+		//exit(0);
+	}
+	int random_numbers[10] = {199, 123, 213, 333, 4123, 3213, 3332, 978, 404, 243};
+	int ind, row, col;
+	int num;
+	do {
+		index_random++;
+		index_random = index_random % 10;
+		ind = random_numbers[index_random] % ((cur_game->rows) * (cur_game->cols));
+		col = ind % (cur_game->cols);
+		row = ind / cur_game->cols;
+	} while ( *get_cell(cur_game, row, col) != -1);
+	//*get_cell(cur_game, row, col) = 2;
+	num = random_numbers[index_random] % 20;
+	if (num <= 1) {
+		*get_cell(cur_game, row, col) = 4; // 1/10th chance
+	}
+	else {
+		*get_cell(cur_game, row, col) = 2;// 9/10th chance
+	}
+}
+
+int print_game(game * cur_game)
+{
+	cell * cell_ptr;
+	cell_ptr = 	cur_game->cells;
+
+	int rows = cur_game->rows;
+	int cols = cur_game->cols;
+	int i, j;
+
+	printf("\n\n\nscore:%d\n", cur_game->score);
+
+
+	printf("|"); // topleft box char
+	for (i = 0; i < cols * 5; i++)
+		printf("-"); // top box char
+	printf("|\n"); //top right char
+
+
+	for (i = 0; i < rows; i++) {
+		printf("|"); // side box char
+		for (j = 0; j < cols; j++) {
+			if ((*cell_ptr) == -1 ) { //print asterisks
+				printf(" **  ");
+			}
+			else {
+				switch ( *cell_ptr ) { //print colored text
+				case 2:
+					printf("  2  ");
+					break;
+				case 4:
+					printf("  4  ");
+					break;
+				case 8:
+					printf("  8  ");
+					break;
+				case 16:
+					printf("  16 ");
+					break;
+				case 32:
+					printf("  32 ");
+					break;
+				case 64:
+					printf("  64 ");
+					break;
+				case 128:
+					printf("  128");
+					break;
+				case 256:
+					printf("  256");
+					break;
+				case 512:
+					printf("  512");
+					break;
+				case 1024:
+					printf(" 1024");
+					break;
+				case 2048:
+					printf(" 2048");
+					break;
+				case 4096:
+					printf(" 4096");
+					break;
+				case 8192:
+					printf(" 8192");
+					break;
+				default:
+					printf("  X  ");
+
+				}
+
+			}
+			cell_ptr++;
+		}
+		printf("|\n"); //print right wall and newline
+	}
+
+	printf("-"); // print bottom left char
+	for (i = 0; i < cols * 5; i++)
+		printf("-"); // bottom char
+	printf("|\n"); //bottom right char
+
+	return 0;
+}
+
+int process_turn(const char input_char, game* cur_game) //returns 1 if legal move is possible after input is processed
+{
+	int rows, cols;
+	char buf[200];
+	char garbage[2];
+	int move_success = 0;
+
+	switch ( input_char ) {
+	case 'w':
+		move_success = move_w(cur_game);
+		break;
+	case 'a':
+		move_success = move_a(cur_game);
+		break;
+	case 's':
+		move_success = move_s(cur_game);
+		//if (move_success) printf("s is pressed\n");
+		break;
+	case 'd':
+		move_success = move_d(cur_game);
+		break;
+	case 'q':
+		destroy_game(cur_game);
+		printf("\nQuitting..\n");
+		return 0;
+		break;
+	/*	case 'n':
+			//get row and col input for new game
+	dim_prompt: printf("NEW GAME: Enter dimensions (rows columns):");
+			while (NULL == fgets(buf, 200, stdin)) {
+				printf("\nProgram Terminated.\n");
+				return 0;
+			}
+
+			if (2 != sscanf(buf, "%d%d%1s", &rows, &cols, garbage) ||
+			        rows < 0 || cols < 0) {
+				printf("Invalid dimensions.\n");
+				goto dim_prompt;
+			}
+
+			remake_game(&cur_game, rows, cols);
+
+			move_success = 1;
+	*/
+	default: //any other input
+		printf("Invalid Input. Valid inputs are: w, a, s, d, q, n.\n");
+	}
+
+
+
+
+	if (move_success == 1) { //if movement happened, insert new tile and print the game.
+		rand_new_tile(cur_game);
+		print_game(cur_game);
+	}
+
+	if ( legal_move_check(cur_game) == 0) { //check if the newly spawned tile results in game over.
+		printf("Game Over!\n");
+		destroy_game(cur_game);
+		return 0;
+	}
+	return 1;
+}
diff --git a/student-distrib/game.h b/student-distrib/game.h
new file mode 100644
index 0000000..a1eaac8
--- /dev/null
+++ b/student-distrib/game.h
@@ -0,0 +1,41 @@
+#include "lib.h"
+#include "malloc.h"
+
+/*! Defines data type cell, which functions identically to type int. */
+typedef int cell;
+
+/*! Defines a game, which is a just a grid of cells and game score. */
+typedef struct 
+{
+	/* Number of rows in the grid */
+    int rows;
+	
+	/* Number of columns in the grid */
+	int cols;
+	
+	/* Pointer to the beginning of the board cell data.  The cells are organized
+       in a 1D array in a row-major layout ( http://en.wikipedia.org/wiki/Row-major_order ) */
+    cell * cells;
+	
+	/* Score of current game. */
+	int score;
+	
+} game;
+
+
+game * make_game(int rows, int cols);
+void destroy_game(game * cur_game);
+
+cell * get_cell(game * cur_game, int row, int col);
+
+int move_w(game * cur_game);
+int move_s(game * cur_game);
+int move_a(game * cur_game);
+int move_d(game * cur_game);
+
+int legal_move_check(game * cur_game);
+void remake_game(game ** _cur_game,int new_rows,int new_cols);
+
+int process_turn(const char input_char, game* cur_game);
+int print_game(game * cur_game);
+void rand_new_tile(game * cur_game);
diff --git a/student-distrib/keyboard_handler.c b/student-distrib/keyboard_handler.c
index bd5d2c4..4a91d70 100644
--- a/student-distrib/keyboard_handler.c
+++ b/student-distrib/keyboard_handler.c
@@ -6,6 +6,7 @@
 #include "pit.h"
 #include "schedule.h"
 #include "systemcall.h"
+#include "2048.h"
 
 
 #define KEYBRD_DATA_PORT 0x60
@@ -32,7 +33,7 @@
 #define DISPLAY 0xFF
 #define ATTRIB 0x7
 uint32_t terminal_id = 0;
-uint32_t key_buff_size[SCREEN_LIMIT] = {0,0,0};
+uint32_t key_buff_size[SCREEN_LIMIT] = {0, 0, 0};
 static int32_t s;
 static uint8_t temp;
 static uint8_t pre_ATTRIB;
@@ -42,42 +43,42 @@ static uint8_t pre_ATTRIB;
  */
 static unsigned char kbdus[128] =
 {
-    0,  27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
-  '9', '0', '-', '=', '\b', /* Backspace */
-  '\t',     /* Tab */
-  'q', 'w', 'e', 'r', /* 19 */
-  't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
-    0,      /* 29   - Control */
-  'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
- '\'', '`',   0,    /* Left shift */
- '\\', 'z', 'x', 'c', 'v', 'b', 'n',      /* 49 */
-  'm', ',', '.', '/',   0,        /* Right shift */
-  '*',
-    0,  /* Alt */
-  ' ',  /* Space bar */
-    0,  /* Caps lock */
-    0,  /* 59 - F1 key ... > */
-    0,   0,   0,   0,   0,   0,   0,   0,
-    0,  /* < ... F10 */
-    0,  /* 69 - Num lock*/
-    0,  /* Scroll Lock */
-    0,  /* Home key */
-    0,  /* Up Arrow */
-    0,  /* Page Up */
-  '-',
-    0,  /* Left Arrow */
-    0,
-    0,  /* Right Arrow */
-  '+',
-    0,  /* 79 - End key*/
-    0,  /* Down Arrow */
-    0,  /* Page Down */
-    0,  /* Insert Key */
-    0,  /* Delete Key */
-    0,   0,   0,
-    0,  /* F11 Key */
-    0,  /* F12 Key */
-    0,  /* All other keys are undefined */
+	0,  27, '1', '2', '3', '4', '5', '6', '7', '8', /* 9 */
+	'9', '0', '-', '=', '\b', /* Backspace */
+	'\t',     /* Tab */
+	'q', 'w', 'e', 'r', /* 19 */
+	't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', /* Enter key */
+	0,      /* 29   - Control */
+	'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 39 */
+	'\'', '`',   0,    /* Left shift */
+	'\\', 'z', 'x', 'c', 'v', 'b', 'n',      /* 49 */
+	'm', ',', '.', '/',   0,        /* Right shift */
+	'*',
+	0,  /* Alt */
+	' ',  /* Space bar */
+	0,  /* Caps lock */
+	0,  /* 59 - F1 key ... > */
+	0,   0,   0,   0,   0,   0,   0,   0,
+	0,  /* < ... F10 */
+	0,  /* 69 - Num lock*/
+	0,  /* Scroll Lock */
+	0,  /* Home key */
+	0,  /* Up Arrow */
+	0,  /* Page Up */
+	'-',
+	0,  /* Left Arrow */
+	0,
+	0,  /* Right Arrow */
+	'+',
+	0,  /* 79 - End key*/
+	0,  /* Down Arrow */
+	0,  /* Page Down */
+	0,  /* Insert Key */
+	0,  /* Delete Key */
+	0,   0,   0,
+	0,  /* F11 Key */
+	0,  /* F12 Key */
+	0,  /* All other keys are undefined */
 };
 
 static uint32_t ctrl_pressed = 0;											//initialze value for the flags
@@ -95,16 +96,16 @@ static uint32_t alt_pressed = 0;
 void switch_terminal (uint32_t target_screen, uint32_t screen_size)
 {
 	//calculating the high byte and display to the screen
-	uint8_t high_byte = (screen_size*target_screen >> 8) & DISPLAY;
+	uint8_t high_byte = (screen_size * target_screen >> 8) & DISPLAY;
 	outb(HIGHBIT, VGA_REG_SWITCH1);
 	outb(high_byte, VGA_REG_SWITCH2);
 	//calculating the low byte and display to the screen
-	uint8_t low_byte = (screen_size*target_screen) & DISPLAY;
+	uint8_t low_byte = (screen_size * target_screen) & DISPLAY;
 	outb(LOWBIT, VGA_REG_SWITCH1);
 	outb(low_byte, VGA_REG_SWITCH2);
 
-	*(uint8_t *)(VIDEO_MEM + 2*SCREEN_SIZE*terminal_id + (s << 1)) = temp;
-    *(uint8_t *)(VIDEO_MEM + 2*SCREEN_SIZE*terminal_id + (s << 1) + 1) = pre_ATTRIB;
+	*(uint8_t *)(VIDEO_MEM + 2 * SCREEN_SIZE * terminal_id + (s << 1)) = temp;
+	*(uint8_t *)(VIDEO_MEM + 2 * SCREEN_SIZE * terminal_id + (s << 1) + 1) = pre_ATTRIB;
 	terminal_id = target_screen;
 
 	//call paging and set up new pages for video mem
@@ -119,143 +120,146 @@ void switch_terminal (uint32_t target_screen, uint32_t screen_size)
 */
 
 void keyboard_handler(void)
-{       
-		//get the scancode
-        uint8_t scancode = inb(KEYBRD_DATA_PORT);
-        uint8_t key; 						
-          //printf("enter keyboard handler\n");
-		if (scancode == LEFT_SHIFT_PRESS)
-			shift_pressed = 1;	
-		if (scancode == LEFT_SHIFT_PRESS + bit_mask)
-			shift_pressed = 0;
-		if (scancode == RIGHT_SHIFT_PRESS)
-			shift_pressed = 1;
-		if (scancode == RIGHT_SHIFT_PRESS + bit_mask)
-			shift_pressed = 0;
-		if (scancode == CTRL_PRESS)				
-			ctrl_pressed = 1;
-		if (scancode == CTRL_PRESS + bit_mask)
-			ctrl_pressed = 0;
-		if (scancode == ALT_PRESS)
-			alt_pressed = 1;
-		if (scancode == ALT_PRESS + bit_mask)
-			alt_pressed = 0;
-		if (scancode == CAPSLOCK_PRESS)
-			capslock_press = 1 - capslock_press;
+{
+	//get the scancode
+	uint8_t scancode = inb(KEYBRD_DATA_PORT);
+	uint8_t key;
+	//printf("enter keyboard handler\n");
+	if (scancode == LEFT_SHIFT_PRESS)
+		shift_pressed = 1;
+	if (scancode == LEFT_SHIFT_PRESS + bit_mask)
+		shift_pressed = 0;
+	if (scancode == RIGHT_SHIFT_PRESS)
+		shift_pressed = 1;
+	if (scancode == RIGHT_SHIFT_PRESS + bit_mask)
+		shift_pressed = 0;
+	if (scancode == CTRL_PRESS)
+		ctrl_pressed = 1;
+	if (scancode == CTRL_PRESS + bit_mask)
+		ctrl_pressed = 0;
+	if (scancode == ALT_PRESS)
+		alt_pressed = 1;
+	if (scancode == ALT_PRESS + bit_mask)
+		alt_pressed = 0;
+	if (scancode == CAPSLOCK_PRESS)
+		capslock_press = 1 - capslock_press;
+
+	if ((scancode == F1) && (alt_pressed == 1))
+		switch_terminal(0, SCREEN_SIZE);
+	if ((scancode == F2) && (alt_pressed == 1))
+		switch_terminal(1, SCREEN_SIZE);
+	if ((scancode == F3) && (alt_pressed == 1))
+		switch_terminal(2, SCREEN_SIZE);
+	//scancode & 0x80 means that key is released. ! means press.
+	if (!(scancode & bit_mask)) {
+		key = kbdus[scancode];
+		if (shift_pressed == 1)
+		{
+			if (key == '1')
+				key = '!';
+			else if (key == '2') {
+				send_eoi(1);
+				start_2048();
+				key = '@';
+			}
+			else if (key == '3')
+				key = '$';
+			else if (key == '4')
+				key = '$';
+			else if (key == '5')
+				key = '%';
+			else if (key == '6')
+				key = '^';
+			else if (key == '7')
+				key = '&';
+			else if (key == '8')
+				key = '*';
+			else if (key == '9')
+				key = '(';
+			else if (key == '0')
+				key = ')';
+			else if (key == '-')
+				key = '_';
+			else if (key == '=')
+				key = '+';
+			else if (key == ',')
+				key = '<';
+			else if (key == '.')
+				key = '.';
+			else if (key == '/')
+				key = '?';
+			else if (key >= 'a' && key <= 'z')
+				key = key - 32;
+			else
+				;
+		}
+
+		if (capslock_press == 1)
+		{
+			if (key >= 'a' && key <= 'z')
+				key = key - 32;
+		}
+		// keyboard buff implement
+		// how to put a NULL at the end??
 
-		if ((scancode == F1) && (alt_pressed == 1))
-			switch_terminal(0, SCREEN_SIZE);
-		if ((scancode == F2) && (alt_pressed == 1))
-			switch_terminal(1, SCREEN_SIZE);
-		if ((scancode == F3) && (alt_pressed == 1))
-			switch_terminal(2, SCREEN_SIZE);
-		//scancode & 0x80 means that key is released. ! means press.
-        if(!(scancode & bit_mask)){
-                key = kbdus[scancode];                 
-			  if (shift_pressed == 1)
-			    {
-			      if(key == '1')
-			        key = '!';
-			      else if(key == '2')
-			        key = '@';
-			      else if(key == '3')
-			        key = '$';
-			      else if(key == '4')
-			        key = '$';
-			      else if(key == '5')
-			        key = '%';
-			      else if(key == '6')
-			        key = '^';
-			      else if(key == '7')
-			        key = '&';
-			      else if(key == '8')
-			        key = '*';
-			      else if(key == '9')
-			        key = '(';
-			      else if(key == '0')
-			        key = ')';
-			      else if(key == '-')
-			        key = '_';
-			      else if(key == '=')
-			        key = '+';
-			      else if(key == ',')
-			        key = '<';
-			      else if(key == '.')
-			        key = '.';
-			      else if(key == '/')
-			        key = '?';
-			      else if(key>='a' &&key<='z')
-			          key = key-32;
-			      else
-			          ;
-			    }
+		if (((key == 'L') || (key == 'l')) && ctrl_pressed == 1) {
+			clear ();									//clear screen
+			send_eoi(1);
+			return;
+		}
+		if (key == 's' && alt_pressed == 1)
+		{
+			song();
+			send_eoi(1);
+			return;
+		}
 
-					if (capslock_press == 1)
-				    {
-				      if(key>='a' &&key<='z')
-				          key = key-32;
-				    }
-				     // keyboard buff implement
-    				// how to put a NULL at the end??
-					
-            		if (((key == 'L') || (key == 'l')) && ctrl_pressed == 1){
-            			clear ();									//clear screen 
-            			send_eoi(1);
-            			return;
-            		}
-            		if(key == 's' && alt_pressed==1)
-            		{
-            			song();
-            			send_eoi(1);
-            			return;
-            		}
+		//edge case
+		if (scancode != 0x0E && key != '\n' && (key >= ' ' && key <= '~') && key != '\0') {
+			if (key_buff_size[terminal_id] == BUFF_SIZE_LIMIT)
+				;
+			else {
+				key_buf[key_buff_size[terminal_id]][terminal_id] = key;
+				key_buff_size[terminal_id] ++;
+				//print would cause cursor error
+				putc (key, 1);
+			}
+		}
+		//backspace implement
+		if (scancode == 0x0E) {
+			if (key_buff_size[terminal_id] > 0) {
+				key_buff_size[terminal_id] --;
+				backspace();
+				key_buf[key_buff_size[terminal_id]][terminal_id] = BUFF_END;
+			}
+		}
+		//enter case
+		if (key == '\n') {
 
-            		//edge case
-            		if (scancode != 0x0E && key != '\n' && (key >=' ' && key <= '~') && key!='\0'){
-            			if (key_buff_size[terminal_id] == BUFF_SIZE_LIMIT)			
-            				;
-            			else {
-            				key_buf[key_buff_size[terminal_id]][terminal_id] = key;
-							key_buff_size[terminal_id] ++;	
-							//print would cause cursor error				
-							putc (key, 1);
-            			}
-            		}
-            		//backspace implement
-            		if (scancode == 0x0E){						
-						if(key_buff_size[terminal_id] > 0){					
-							key_buff_size[terminal_id] --;
-							backspace();						
-							key_buf[key_buff_size[terminal_id]][terminal_id] = BUFF_END; 
-						}
-            		}
-            		//enter case
-            		if(key == '\n'){   					
+			if (key_buff_size[terminal_id] < BUFF_SIZE_LIMIT) {
+				key_buf[key_buff_size[terminal_id]][terminal_id] = '\n';
 
-            			if (key_buff_size[terminal_id] < BUFF_SIZE_LIMIT){
-            				key_buf[key_buff_size[terminal_id]][terminal_id] = '\n';
+				key_buf[key_buff_size[terminal_id] + 1][terminal_id] = BUFF_END;
 
-            				key_buf[key_buff_size[terminal_id] + 1][terminal_id] = BUFF_END;
+				key_buff_size[terminal_id] = key_buff_size[terminal_id] + 1;
+				//putc (key, 1);
+			}
+			else
+				key_buf[key_buff_size[terminal_id]][terminal_id] = BUFF_END;		//store to the buffer
+			uint32_t j;
+			for (j = 0; j < key_buff_size[terminal_id] + 1; j++)
+			{
+				out_buf[j][terminal_id] = key_buf[j][terminal_id];					//move all key_buffer value to out_buffer
+				key_buf[j][terminal_id] = '\0'; //clear buff
+			}
+			key_buff_size[terminal_id] = 0;
+			read_ready = 0;   //send read signal
+			putc (key , 1);
+		}
 
-            				key_buff_size[terminal_id] = key_buff_size[terminal_id] + 1;
-            				//putc (key, 1);
-            			}
-            		else
-						key_buf[key_buff_size[terminal_id]][terminal_id] = BUFF_END;		//store to the buffer
-						uint32_t j;
-						for(j=0; j<key_buff_size[terminal_id]+1; j++)
-						{
-							out_buf[j][terminal_id] = key_buf[j][terminal_id];					//move all key_buffer value to out_buffer
-							key_buf[j][terminal_id] = '\0'; //clear buff
-						}					
-						key_buff_size[terminal_id] = 0;						
-						read_ready = 0;   //send read signal
-						putc (key , 1);
-					}
-            									
-                }
-        send_eoi(1);    //send eoi when  done
-        return;
+	}
+	send_eoi(1);    //send eoi when  done
+	return;
 }
 
 
diff --git a/student-distrib/malloc.c b/student-distrib/malloc.c
index be75420..15f38a4 100644
--- a/student-distrib/malloc.c
+++ b/student-distrib/malloc.c
@@ -20,7 +20,7 @@ uint32_t * malloc(uint32_t size) {
 	int new_index = 0;
 	int check_space_index, check_space_flag;
 	while (new_index < KB_4) {
-		if (!dynamic_memory_table[new_index]) 
+		if (dynamic_memory_table[new_index] != 0) 
 			new_index += dynamic_memory_table[new_index];
 		else {
 			//check if we have enough consecutive availble space
@@ -37,7 +37,7 @@ uint32_t * malloc(uint32_t size) {
 
 	dynamic_memory_table[new_index] = KB_size;
 
-	return (uint32_t*)(DYNAMIC_ADDR_START + KB_size * KB_1);
+	return (uint32_t*)(DYNAMIC_ADDR_START + new_index * KB_1);
 }
 
 uint32_t free(uint32_t * arg){
-- 
GitLab