initial
This commit is contained in:
commit
daa9fee4c4
|
@ -0,0 +1,21 @@
|
|||
CFLAGS = -Wall -g
|
||||
#-Wall -g -O3
|
||||
SRCS = eleven.core.c eleven.term.c
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
default: eleven.term
|
||||
|
||||
eleven.core.o: eleven.core.c eleven.h
|
||||
gcc $(CFLAGS) -c eleven.core.c -o eleven.core.o
|
||||
|
||||
eleven.term.o: eleven.term.c eleven.h
|
||||
gcc $(CFLAGS) -c eleven.term.c -o eleven.term.o
|
||||
|
||||
eleven.term: eleven.core.o eleven.term.o
|
||||
gcc $(CFLAGS) -o eleven eleven.core.o eleven.term.o
|
||||
strip eleven
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f eleven
|
||||
rm -f *~
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h> //memcpy
|
||||
//https://gist.github.com/ibaned/41481b2fdddbb61a4291
|
||||
#include "eleven.h"
|
||||
|
||||
/* The game state is represented by a 4x4 U8 array. The low nybble
|
||||
contains the numeric value of the tile (0 means empty). The high
|
||||
nybble contains the tile status:
|
||||
2 = newly-spawned;
|
||||
1 = displaced
|
||||
0 = static
|
||||
|
||||
The board must be square, as rotation is implemented as a flip/twist
|
||||
combination of some sort.
|
||||
|
||||
|
||||
|
||||
void pr(U8* tiles){
|
||||
for(int i=0;i<4;i++){
|
||||
for(int j=0;j<4;j++){
|
||||
printf("%02X ",*(tiles+i*SIZE+j));
|
||||
}
|
||||
printf("\n");
|
||||
}}
|
||||
*/
|
||||
#define RND (rand()%SIZE)
|
||||
|
||||
void twist(U8* tiles){
|
||||
int i,j;
|
||||
U8 t2[SIZE*SIZE];
|
||||
for (i = 0; i < SIZE; ++i)
|
||||
for (j = 0; j < SIZE; ++j)
|
||||
t2[i*SIZE+j] = tiles[j*SIZE+i];
|
||||
memcpy(tiles,t2,SIZE*SIZE);
|
||||
}
|
||||
|
||||
void flip(U8* tiles){
|
||||
int i,j;
|
||||
U8 t2[SIZE*SIZE];
|
||||
for (i = 0; i < SIZE; ++i)
|
||||
for (j = 0; j < SIZE; ++j)
|
||||
t2[i*SIZE+j] = tiles[i*SIZE+(SIZE - j - 1)];
|
||||
memcpy(tiles,t2,SIZE*SIZE);
|
||||
}
|
||||
|
||||
void spawn(U8* tiles){;
|
||||
while (1) {
|
||||
int i = RND;
|
||||
int j = RND;
|
||||
if (!tiles[i*SIZE+j]) {
|
||||
tiles[i*SIZE+j] = (rand() % 10) ? 0x21 : 0x22; // 2 status means new
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
int dif(U8*new, U8*old){
|
||||
int i,n;
|
||||
n=0; //number of changes
|
||||
for (i = 0; i < SIZE*SIZE; ++i){
|
||||
if (new[i] && (new[i] != old[i])){
|
||||
new[i] += 0x10;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void init(U8* tiles){
|
||||
memset(tiles,0,SIZE*SIZE);
|
||||
tiles[0]=8;
|
||||
tiles[4]=7;
|
||||
tiles[8]=6;
|
||||
tiles[12]=5;
|
||||
|
||||
tiles[1]=4;
|
||||
tiles[5]=3;
|
||||
tiles[9]=2;
|
||||
tiles[13]=1;
|
||||
spawn((U8*)tiles);
|
||||
spawn((U8*)tiles);
|
||||
}
|
||||
|
||||
void drop_col(U8* a, U8* b){
|
||||
int i,j;
|
||||
int prev = 0;
|
||||
j = 0;
|
||||
for (i = 0; i < SIZE; ++i){
|
||||
if (a[i]) {
|
||||
if ( (0xF & a[i]) == prev) {
|
||||
b[j-1]++;
|
||||
prev = 0;
|
||||
} else {
|
||||
b[j++] = a[i];
|
||||
prev = (0xF & a[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U32 drop(U8* tiles){
|
||||
U8 t2[SIZE*SIZE];
|
||||
memset(t2,0,SIZE*SIZE);
|
||||
|
||||
for (int i = 0; i < SIZE*SIZE; i=i+SIZE)
|
||||
drop_col(tiles+i, ((U8*)t2)+i);
|
||||
|
||||
U32 n = dif(t2,tiles); // return the dif count
|
||||
memcpy(tiles,t2,SIZE*SIZE);
|
||||
return n;
|
||||
}
|
||||
|
||||
void map_clear(U8* tiles){
|
||||
int i;
|
||||
for (i = 0; i < SIZE*SIZE; ++i)
|
||||
tiles[i] &= 0xF;
|
||||
}
|
||||
|
||||
U32 step(U8* tiles){
|
||||
map_clear(tiles);
|
||||
U8 old[SIZE*SIZE];
|
||||
memcpy(old,tiles,SIZE*SIZE);
|
||||
U32 dif;
|
||||
if((dif=drop(tiles))) //return difference count
|
||||
spawn(tiles);
|
||||
return dif;
|
||||
}
|
||||
|
||||
|
||||
U32 move(U8* tiles, int way){
|
||||
if (way / 2) twist(tiles);
|
||||
if (way % 2) flip(tiles);
|
||||
U32 n = step(tiles);
|
||||
if (way % 2) flip(tiles);
|
||||
if (way / 2) twist(tiles);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
#include <stdint.h>
|
||||
#define SIZE 4
|
||||
typedef uint8_t U8;
|
||||
typedef uint32_t U32;
|
||||
|
||||
typedef U8 (*pTiles)[SIZE][SIZE];
|
||||
|
||||
|
||||
enum {
|
||||
DOWN, //0
|
||||
UP, //1
|
||||
LEFT, //2
|
||||
RIGHT,
|
||||
MOVES
|
||||
};
|
||||
|
||||
void init(U8* tiles);
|
||||
|
||||
U32 move(U8* tiles, int way);
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
//https://gist.github.com/ibaned/41481b2fdddbb61a4291
|
||||
#include "eleven.h"
|
||||
|
||||
const char* tochar(int val){
|
||||
// int i = 'A'-2;
|
||||
const char* chars[] = //{"①","②","③","④","⑤","⑥","⑦","⑧","⑨","⑩","⑪","⑫","⑬","⑭","⑮","⑯"} ;
|
||||
{" ","➊","➋","➌","➍","➎","➏","➐","➑","➒","➓","⓫","⓬","⓭","⓮","⓯"};//,"⓰","⓱","⓲","⓳","⓴"
|
||||
return chars[val & 0xF];
|
||||
}
|
||||
|
||||
void format_cell_2(char* buf,U8 val){
|
||||
sprintf(buf,"%s", tochar(val));
|
||||
}
|
||||
void format_cell_256(char* buf,U8 val){
|
||||
// const U8 col[9]={196,1,161,126,91,62,27,27,27};
|
||||
//const U8 col[9]={196,207,171,135,99,63,27,27,27};
|
||||
//const U8 col[9]={202,219,183,147,111,75,39,39,39};
|
||||
const U8 col[3]={33,141,196};
|
||||
U32 icol = val>>4;
|
||||
|
||||
sprintf(buf,"\033[38;5;%dm%s\033[m", col[icol],tochar(val));
|
||||
}
|
||||
|
||||
void print(U8* tiles){
|
||||
int i,j;
|
||||
char buf[32];
|
||||
|
||||
printf("╭────────╮\n");
|
||||
for (j = SIZE - 1; j >= 0; --j) {
|
||||
printf("│");
|
||||
for (i = 0; i < SIZE; ++i) {
|
||||
format_cell_256(buf,tiles[i*SIZE+j]);
|
||||
printf("%s ", buf);
|
||||
}
|
||||
printf("│ ");
|
||||
// for (i = 0; i < SIZE; ++i) printf("%X ", (tiles[i*SIZE+j]));
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
printf("╰────────╯\n");
|
||||
}
|
||||
|
||||
int read_move(void){
|
||||
char keys[MOVES] = {'k','i','j','l'};
|
||||
int c;
|
||||
int i;
|
||||
while (isspace(c = getchar()));
|
||||
if (c == EOF)
|
||||
return c;
|
||||
for (i = 0; i < MOVES; ++i)
|
||||
if (c == keys[i])
|
||||
return i;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
static struct termios backup;
|
||||
static struct termios current;
|
||||
|
||||
void take_stdin(void){
|
||||
tcgetattr(STDIN_FILENO, &backup);
|
||||
current = backup;
|
||||
current.c_lflag &= (~ICANON & ~ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, ¤t);
|
||||
}
|
||||
|
||||
void give_stdin(void){
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &backup);
|
||||
}
|
||||
|
||||
#include <time.h>
|
||||
int main(){
|
||||
int moves=0;
|
||||
int c;
|
||||
U8 tiles[] = {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
|
||||
srand(time(0));
|
||||
init(tiles);
|
||||
print(tiles);
|
||||
take_stdin();
|
||||
while ((c = read_move()) != EOF) {
|
||||
if(move(tiles, c)){
|
||||
moves++;
|
||||
print(tiles);
|
||||
}
|
||||
else {
|
||||
// zeros++;
|
||||
// if(zeros>4)
|
||||
// printf("Ready to give up?\n");
|
||||
}
|
||||
}
|
||||
printf("%d moves\n",moves);
|
||||
give_stdin();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue