#ifndef MOVE_H
#define MOVE_H
#define MOVE_UP 1
#define MOVE_DOWN 2
#define MOVE_LEFT 4
#define MOVE_RIGHT 8
void initField(tHandle* handle);
int newTile(tHandle* handle);
int checkMoveable(tHandle* handle);
int makeMove(tHandle *handle,tUInt8 move);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
#include "Config.h"
#include "Datatypes.h"
#include "Move.h"
#include "Output.h"
void initField(tHandle* handle)
{
int i;
int j;
for (i=0;i<TILE_ROWS;i++)
{
for (j=0;j<TILE_COLS;j++)
{
handle->actField.tile[i][j]=0;
}
}
handle->score=0;
}
int newTile(tHandle* handle)
{
int i;
int j;
tUInt32 r;
int pos[TILE_MASK+1];
tField nxtField;
int cnt;
cnt=0;
for (i=0; i<TILE_ROWS; i++)
{
for (j=0; j<TILE_COLS; j++)
{
if ( !handle->actField.tile[i][j])
pos[cnt++] = i * TILE_COLS + j;
}
}
if (cnt)
{
memcpy(&nxtField, &(handle->actField), sizeof(tField));
r=cnt;
while ( r >= cnt )
{
r = rand()&TILE_MASK;
}
cnt = pos[r];
r = rand();
if (r<0) r = -r;
if ((r%TILE_4_PROB)==0) r=4;
else r = 2;
i = cnt/TILE_ROWS;
j = cnt%TILE_ROWS;
nxtField.tile[i][j] = r;
// TODO: spawnTile(handle,i,j);
memcpy(&(handle->actField), &nxtField, sizeof(tField));
return 1;
}
else
{
return 0;
}
}
int checkMoveable(tHandle* handle)
{
int i,j;
int retval=0;
for (i=0; i<TILE_ROWS; i++)
{
for (j=0; j<TILE_COLS; j++)
{
int x, y;
x = handle->actField.tile[i][j];
if (x)
{
if (j!=0)
{
y = handle->actField.tile[i][j-1];
if (y==0) retval |= MOVE_LEFT;
if (x==y) retval |= (MOVE_LEFT|MOVE_RIGHT);
}
if (j != TILE_COLS-1)
{
y = handle->actField.tile[i][j+1];
if (y == 0) retval |= MOVE_RIGHT;
if (x == y) retval |= (MOVE_LEFT|MOVE_RIGHT);
}
}
}
}
for (i=0; i<TILE_COLS; i++)
{
for (j=0;j<TILE_ROWS;j++)
{
int x,y;
x=handle->actField.tile[j][i];
if (x)
{
if (j!=0)
{
y=handle->actField.tile[j-1][i];
if (y==0) retval|=MOVE_UP;
if (x==y) retval|=(MOVE_UP|MOVE_DOWN);
}
if (j!=TILE_ROWS-1)
{
y=handle->actField.tile[j+1][i];
if (y==0) retval|=MOVE_DOWN;
if (x==y) retval|=(MOVE_UP|MOVE_DOWN);
}
}
}
}
return retval;
}
int makeMove(tHandle *handle,tUInt8 move)
{
signed int i,j,k;
int moved;
moved=0;
i=checkMoveable(handle);
if (i&move)
{
switch (move)
{
case MOVE_UP:
//
for (i=0; i<TILE_COLS; i++)
{
int newpos[TILE_ROWS];
int newTiles[TILE_ROWS];
int combined[TILE_ROWS];
for (j=0; j<TILE_ROWS; j++)
{
combined[j]=0;
newTiles[j]=handle->actField.tile[j][i];
newpos[j]=j;
}
for (j=0;j<TILE_ROWS;j++)
{
int found;
combined[j]=0;
if (newTiles[j])
{
found=-1;
for (k=j-1;k>=0 && found==-1;k--)
{
if (newTiles[k]==0) newpos[j]=k;
else found=k;
}
found=-1;
for (k=j+1;k<TILE_ROWS && found==-1;k++)
{
if (newTiles[k])
{
found=k;
if (newTiles[j]==newTiles[k])
{
handle->score+=newTiles[j];
newpos[k]=newpos[j];
newTiles[j]*=2;
newTiles[k]=0;
combined[j]=1;
moved=1;
}
}
}
if (newpos[j]!=j)
{
transition(handle,handle->actField.tile[j][i], j,newpos[j], i,i);
combined[newpos[j]]=combined[j];
newTiles[newpos[j]]=newTiles[j];
newTiles[j]=0;
combined[j]=0;
moved=1;
}
}
}
// TODO: transition
for (j=0;j<TILE_ROWS;j++)
{
handle->actField.tile[j][i]=newTiles[j];
}
}
break;
case MOVE_DOWN:
//
for (i=0;i<TILE_COLS;i++)
{
int newpos[TILE_ROWS];
int newTiles[TILE_ROWS];
int combined[TILE_ROWS];
for (j=TILE_ROWS-1;j>=0;j--)
{
combined[j]=0;
newTiles[j]=handle->actField.tile[j][i];
newpos[j]=j;
}
for (j=TILE_ROWS-1;j>=0;j--)
{
int found;
combined[j]=0;
newpos[j]=j;
if (newTiles[j])
{
found=-1;
for (k=j+1;k<TILE_ROWS && found==-1;k++)
{
if (newTiles[k]==0) newpos[j]=k;
else found=k;
}
found=-1;
for (k=j-1;k>=0 && found==-1;k--)
{
if (newTiles[k])
{
found=k;
if (newTiles[j]==newTiles[k])
{
handle->score+=newTiles[j];
newpos[k]=newpos[j];
newTiles[j]*=2;
newTiles[k]=0;
combined[j]=1;
moved=1;
}
}
}
if (newpos[j]!=j)
{
transition(handle,handle->actField.tile[j][i], j,newpos[j], i,i);
combined[newpos[j]]=combined[j];
newTiles[newpos[j]]=newTiles[j];
newTiles[j]=0;
combined[j]=0;
moved=1;
}
}
}
// TODO: transition
for (j=0;j<TILE_ROWS;j++)
{
handle->actField.tile[j][i]=newTiles[j];
}
}
break;
case MOVE_LEFT:
//
for (i=0;i<TILE_ROWS;i++)
{
int newpos[TILE_COLS];
int newTiles[TILE_COLS];
int combined[TILE_COLS];
for (j=0;j<TILE_COLS;j++)
{
combined[j]=0;
newTiles[j]=handle->actField.tile[i][j];
newpos[j]=j;
}
for (j=0;j<TILE_COLS;j++)
{
int found;
combined[j]=0;
newpos[j]=j;
if (newTiles[j])
{
found=-1;
for (k=j-1;k>=0 && found==-1;k--)
{
if (newTiles[k]==0) newpos[j]=k;
else found=k;
}
found=-1;
for (k=j+1;k<TILE_COLS && found==-1;k++)
{
if (newTiles[k])
{
found=k;
if (newTiles[j]==newTiles[k])
{
handle->score+=newTiles[j];
newpos[k]=newpos[j];
newTiles[j]*=2;
newTiles[k]=0;
combined[j]=1;
moved=1;
}
}
}
if (newpos[j]!=j)
{
transition(handle,handle->actField.tile[i][j], i,i, j,newpos[j]);
combined[newpos[j]]=combined[j];
newTiles[newpos[j]]=newTiles[j];
newTiles[j]=0;
combined[j]=0;
moved=1;
}
}
}
// TODO: transition
for (j=0;j<TILE_COLS;j++)
{
handle->actField.tile[i][j]=newTiles[j];
}
}
break;
case MOVE_RIGHT:
//
for (i=0;i<TILE_ROWS;i++)
{
int newpos[TILE_COLS];
int newTiles[TILE_COLS];
int combined[TILE_COLS];
for (j=TILE_COLS-1;j>=0;j--)
{
combined[j]=0;
newTiles[j]=handle->actField.tile[i][j];
newpos[j]=j;
}
for (j=TILE_COLS-1;j>=0;j--)
{
int found;
combined[j]=0;
newpos[j]=j;
if (newTiles[j])
{
found=-1;
for (k=j+1;k<TILE_COLS && found==-1;k++)
{
if (newTiles[k]==0) newpos[j]=k;
else found=k;
}
found=-1;
for (k=j-1;k>=0 && found==-1;k--)
{
if (newTiles[k])
{
found=k;
if (newTiles[j]==newTiles[k])
{
handle->score+=newTiles[j];
newpos[k]=newpos[j];
newTiles[j]*=2;
newTiles[k]=0;
combined[j]=1;
moved=1;
}
}
}
if (newpos[j]!=j)
{
transition(handle,handle->actField.tile[i][j], i,i, j,newpos[j]);
combined[newpos[j]]=combined[j];
newTiles[newpos[j]]=newTiles[j];
newTiles[j]=0;
combined[j]=0;
moved=1;
}
}
}
// TODO: transition
for (j=0;j<TILE_COLS;j++)
{
handle->actField.tile[i][j]=newTiles[j];
}
}
break;
}
if (moved)
{
for (i=0;i<TILE_ROWS;i++)
{
for (j=0;j<TILE_COLS;j++)
{
if (moved<handle->actField.tile[i][j]) moved=handle->actField.tile[i][j];
}
}
}
if (handle->score>handle->best) handle->best=handle->score;
return moved;
} else {
return 0;
}
}