summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasil Zlatanov <v@skozl.com>2017-05-08 00:40:40 +0100
committerVasil Zlatanov <v@skozl.com>2017-05-08 00:40:40 +0100
commit673e4900e93767b8bb3241b89c13424ff6fbf547 (patch)
tree2b5490596f90fd67f3bd0b1267315420c72baf73
parent8bd33441df8ecb4108e69362665f22a2ccf470e8 (diff)
downloade2-switch-673e4900e93767b8bb3241b89c13424ff6fbf547.tar.gz
e2-switch-673e4900e93767b8bb3241b89c13424ff6fbf547.tar.bz2
e2-switch-673e4900e93767b8bb3241b89c13424ff6fbf547.zip
Implement 2048 game prototype
-rw-r--r--src/2048.cpp178
-rw-r--r--src/2048.h17
-rw-r--r--src/main.cpp54
3 files changed, 232 insertions, 17 deletions
diff --git a/src/2048.cpp b/src/2048.cpp
new file mode 100644
index 0000000..13afd1f
--- /dev/null
+++ b/src/2048.cpp
@@ -0,0 +1,178 @@
+/*
+ Date: 2 Feb 2016
+ Author: Vasil Zlatanov
+*/
+
+#include "2048.h"
+#include <stdio.h>
+#include <stdlib.h> //needed for random
+#include <time.h> // needed to for "random" seed
+
+void init(int board[SIZE][SIZE])
+{
+ int x, y;
+ // Load start config
+ for (x = 0; x < SIZE; x++) {
+ for (y = 0; y < SIZE; y++) {
+ board[x][y] = 0;
+ }
+ }
+ board[SIZE - 1][SIZE - 1] = 1;
+}
+
+int move(int direction, int board[SIZE][SIZE]){
+ int done;
+ switch(direction) {
+ case 3 :
+ done = slideLeft(board);
+ break;
+ case 2 :
+ done = slideDown(board);
+ break;
+ case 1 :
+ done = slideUp(board);
+ break;
+ case 0 :
+ done = slideRight(board);
+ break;
+ default :
+ done = 0;
+ }
+ return done;
+}
+
+int slideLeft(int board[SIZE][SIZE])
+{
+ int done;
+ rotate(board);
+ done = slideUp(board);
+ rotate(board);
+ rotate(board);
+ rotate(board);
+ return done;
+}
+
+int slideRight(int board[SIZE][SIZE])
+{
+ int done;
+ rotate(board);
+ rotate(board);
+ rotate(board);
+ done = slideUp(board);
+ rotate(board);
+ return done;
+}
+
+int slideUp(int board[SIZE][SIZE])
+{
+ int done = 0;
+ int x;
+ for (x = 0; x < SIZE; x++) {
+ done |= push(board[x]);
+ }
+ return done;
+}
+
+int slideDown(int board[SIZE][SIZE])
+{
+ int done;
+ rotate(board);
+ rotate(board);
+ done = slideUp(board);
+ rotate(board);
+ rotate(board);
+ return done;
+}
+
+int push(int array[SIZE])
+{
+ int x, n, stop = 0, done = 0;
+ for (x = 1; x < SIZE; x++) {
+ if (array[x] != 0) { // make sure there is something in box
+ done = 2; // don't exit loop until we determine if there is a move
+ for (n = x - 1; done == 2; n--) {
+ if (array[n] != 0) { // if box has number in it
+ if (array[n] == array[x]) { // same so merge
+ array[n]++; // increase by power of two
+ stop = n + 1; // avoid double merge such as 2 2 0 4
+ array[x] = 0;
+ done = 1;
+ } else { // not the same so move just below
+ if (n + 1 != x) {
+ array[n + 1] = array[x];
+ array[x] = 0;
+ done = 1;
+ } else {
+ done = 0; // we can't slide any further
+ }
+ }
+ } else {
+ if (n == stop) {
+ array[stop] = array[x];
+ array[x] = 0;
+ done = 1;
+ }
+ }
+ }
+ }
+ }
+ return done;
+}
+
+void rotate(int board[SIZE][SIZE])
+{
+ int x, y, n = SIZE, temp;
+ for (x = 0; x < n / 2; x++) {
+ for (y = x; y < n - x - 1; y++) {
+ temp = board[x][y];
+ board[x][y] = board[y][n - x - 1];
+ board[y][n - x - 1] = board[n - x - 1][n - y - 1];
+ board[n - x - 1][n - y - 1] = board[n - y - 1][x];
+ board[n - y - 1][x] = temp;
+ }
+ }
+}
+
+int gameover(int board[SIZE][SIZE])
+{
+ int x, y;
+ int nofree = 1;
+ for (x = 0; x < SIZE - 1; x++) {
+ for (y = 0; y < SIZE - 1; y++) {
+ if (board[x][y] == 0) {
+ nofree = 0; // means we have a free square
+ }
+ }
+ }
+
+ if (nofree) {
+ // Check if there is any moves horizontaly or vertically;
+ for (x = 0; x < SIZE - 1; x++) {
+ for (y = 0; y < SIZE - 1; y++) {
+ if ((board[x][y] == board[x][y + 1]) ||
+ (board[x][y] == board[x + 1][y])) {
+ return 0;
+ }
+ }
+ }
+ }
+ return nofree;
+}
+
+void add2(int board[SIZE][SIZE])
+{
+ int x, y, r, pos = 0, free[SIZE * SIZE][2];
+ for (x = 0; x < SIZE; x++) {
+ for (y = 0; y < SIZE; y++) {
+ if (board[x][y] == 0) {
+ free[pos][0] = x;
+ free[pos][1] = y;
+ pos++;
+ }
+ }
+ }
+ if (free > 0) {
+ r = rand() % pos;
+ board[free[r][0]][free[r][1]] = 1;
+ }
+}
diff --git a/src/2048.h b/src/2048.h
new file mode 100644
index 0000000..9b19f64
--- /dev/null
+++ b/src/2048.h
@@ -0,0 +1,17 @@
+#define SIZE 4
+
+int move(int direction, int board[SIZE][SIZE]);
+
+void init(int board[SIZE][SIZE]);
+
+void add2(int board[SIZE][SIZE]);
+
+void rotate(int board[SIZE][SIZE]);
+
+int slideLeft(int board[SIZE][SIZE]);
+int slideRight(int board[SIZE][SIZE]);
+int slideUp(int board[SIZE][SIZE]);
+int slideDown(int board[SIZE][SIZE]);
+int gameover(int board[SIZE][SIZE]);
+
+int push(int array[SIZE]);
diff --git a/src/main.cpp b/src/main.cpp
index 19f280d..229ef25 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,4 +1,5 @@
#include "mbed.h"
+#include "2048.h"
#include "spi_init.h"
#include "counter.h"
#include "Adafruit_SSD1306.h"
@@ -7,15 +8,14 @@
#define SW_PERIOD 20000 // 20ms
void tout(void);
-void pwm_invert(void);
+void draw(int board[4][4]);
// Onboard LED
-DigitalOut out_wave(LED1);
PinName switch_pin[] = { SW_PINS };
Counter *switch_position[4];
Ticker timer;
-Ticker pwm;
+//Ticker pwm;
volatile uint16_t switch_count[4] = { 0, 0, 0, 0 };
volatile uint16_t switch_pressed[4] = { 0, 0, 0, 0 };
@@ -31,6 +31,10 @@ Adafruit_SSD1306_Spi oled(gSpi, D_DC_PIN, D_RST_PIN, D_CS_PIN, 64, 128);
int main(void)
{
+ int done = 0;
+ int board[4][4];
+ init(board);
+
oled.setRotation(2);
wait(0.5);
@@ -43,30 +47,30 @@ int main(void)
timer.attach_us(&tout, SW_PERIOD);
oled.clearDisplay();
- oled.printf("%ux%u Group Ay08-04\r\n", oled.width(), oled.height());
+ oled.printf("%ux%u Group Ay08-04\n", oled.width(), oled.height());
+
+ draw(board);
for (;;) {
if (update) {
update = 0;
+ done = 0;
oled.setTextCursor(0, 0);
//Write the latest switch osciallor count
for (int i = 3; i >= 0; --i) {
- current_f[i] += (switch_pressed[i] && !last_pressed[i]);
- if (current_f[i] > 9)
- current_f[i] = 0;
- oled.printf("\nS:%u C:%05u N:%u", switch_pressed[i], switch_count[i], current_f[i]);
+ if (switch_pressed[i] && !last_pressed[i])
+ done = move(i, board);
}
- uint16_t frequency = 1000*current_f[3] + 100*current_f[2] + 10*current_f[1] + current_f[0];
-
- oled.printf("\nF:%u ", frequency);
+ if(done){
+ add2(board);
+ draw(board);
+ }
- if (frequency < 25)
- pwm.attach_ms(&pwm_invert, 500/frequency);
- else
- pwm.attach_us(&pwm_invert, 500000/frequency);
+ if(gameover(board))
+ oled.printf("\nGame Over!");
//Copy the display buffer to the display
oled.display();
@@ -95,6 +99,22 @@ void tout(void)
update = 1;
}
-void pwm_invert(void){
- out_wave = !out_wave;
+void draw(int board[SIZE][SIZE])
+{
+ int x, y;
+ int value;
+ for (y = 0; y < SIZE; y++) {
+ for (x = 0; x < SIZE; x++) {
+ if (board[x][y] != 0) {
+ value = 2;
+ for (int i = 1; i < board[x][y]; ++i) {
+ value = value * 2;
+ }
+ } else {
+ value = 0;
+ }
+ oled.printf("%d\t", value);
+ }
+ oled.printf("\n");
+ }
}