Init commit
This commit is contained in:
commit
83e6c9e1f0
41 changed files with 1455 additions and 0 deletions
209
code-samples/frogger/src/fsm_matrix.c
Normal file
209
code-samples/frogger/src/fsm_matrix.c
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
#include "fsm.h"
|
||||
|
||||
// This is a finite state machine realisation based on matrix of "actions".
|
||||
/*
|
||||
Function sigact() takes an action function from fsm_table.
|
||||
Game state defines an index of line in matrix (where to get).
|
||||
User signal defines an index of column in matrix (what to get).
|
||||
|
||||
Pros:
|
||||
1) By instantly taking needed action, speed of processing is higher than switch-case realisation.
|
||||
2) Code is easy to read.
|
||||
3) Flexible (easy to add new state)
|
||||
Cons:
|
||||
1) More memory usage.
|
||||
*/
|
||||
|
||||
typedef struct game_params
|
||||
{
|
||||
game_stats_t *stats;
|
||||
frog_state *state;
|
||||
board_t *map;
|
||||
player_pos *frog_pos;
|
||||
bool *break_flag;
|
||||
} params_t;
|
||||
|
||||
typedef void (*action)(params_t *prms);
|
||||
|
||||
void spawn(params_t *prms);
|
||||
void moveup(params_t *prms);
|
||||
void movedown(params_t *prms);
|
||||
void moveright(params_t *prms);
|
||||
void moveleft(params_t *prms);
|
||||
void shifting(params_t *prms);
|
||||
void reach(params_t *prms);
|
||||
void collide(params_t *prms);
|
||||
void gameover(params_t *prms);
|
||||
void exitstate(params_t *prms);
|
||||
void check(params_t *prms);
|
||||
|
||||
action fsm_table[8][7] = {
|
||||
{NULL, NULL, NULL, NULL, exitstate, spawn, NULL},
|
||||
{spawn, spawn, spawn, spawn, spawn, spawn, spawn},
|
||||
{moveup, movedown, moveright, moveleft, exitstate, check, check},
|
||||
{shifting, shifting, shifting, shifting, shifting, shifting, shifting},
|
||||
{reach, reach, reach, reach, reach, reach, reach},
|
||||
{collide, collide, collide, collide, collide, collide, collide},
|
||||
{gameover, gameover, gameover, gameover, gameover, gameover, gameover},
|
||||
{exitstate, exitstate, exitstate, exitstate, exitstate, exitstate, exitstate}
|
||||
};
|
||||
|
||||
void sigact(signals sig, frog_state *state, game_stats_t *stats, board_t *map, player_pos *frog_pos)
|
||||
{
|
||||
params_t prms;
|
||||
prms.stats = stats;
|
||||
prms.state = state;
|
||||
prms.map = map;
|
||||
prms.frog_pos = frog_pos;
|
||||
|
||||
action act = fsm_table[*state][sig];
|
||||
|
||||
if (act)
|
||||
act(&prms);
|
||||
}
|
||||
|
||||
signals get_signal(int user_input)
|
||||
{
|
||||
signals rc = NOSIG;
|
||||
|
||||
if (user_input == KEY_UP)
|
||||
rc = MOVE_UP;
|
||||
else if (user_input == KEY_DOWN)
|
||||
rc = MOVE_DOWN;
|
||||
else if (user_input == KEY_LEFT)
|
||||
rc = MOVE_LEFT;
|
||||
else if (user_input == KEY_RIGHT)
|
||||
rc = MOVE_RIGHT;
|
||||
else if (user_input == ESCAPE)
|
||||
rc = ESCAPE_BTN;
|
||||
else if (user_input == ENTER_KEY)
|
||||
rc = ENTER_BTN;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void shifting(params_t *prms)
|
||||
{
|
||||
shift_map(prms->map);
|
||||
|
||||
if (check_collide(prms->frog_pos, prms->map))
|
||||
*prms->state = COLLIDE;
|
||||
else
|
||||
{
|
||||
*prms->state = MOVING;
|
||||
print_board(prms->map, prms->frog_pos);
|
||||
print_stats(prms->stats);
|
||||
}
|
||||
}
|
||||
|
||||
void check(params_t *prms)
|
||||
{
|
||||
if (check_collide(prms->frog_pos, prms->map))
|
||||
*prms->state = COLLIDE;
|
||||
else if (check_finish_state(prms->frog_pos, prms->map))
|
||||
*prms->state = REACH;
|
||||
else
|
||||
*prms->state = SHIFTING;
|
||||
}
|
||||
|
||||
void spawn(params_t *prms)
|
||||
{
|
||||
if (prms->stats->level > LEVEL_CNT)
|
||||
*prms->state = GAMEOVER;
|
||||
else
|
||||
{
|
||||
if (!lvlproc(prms->map, prms->stats))
|
||||
{
|
||||
fill_finish(prms->map->finish);
|
||||
print_finished(prms->map);
|
||||
frogpos_init(prms->frog_pos);
|
||||
*prms->state = MOVING;
|
||||
}
|
||||
else
|
||||
*prms->state = EXIT_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
void moveup(params_t *prms)
|
||||
{
|
||||
if (prms->frog_pos->y != 1)
|
||||
{
|
||||
CLEAR_BACKPOS(prms->frog_pos->y, prms->frog_pos->x);
|
||||
prms->frog_pos->y -= 2;
|
||||
}
|
||||
|
||||
check(prms);
|
||||
}
|
||||
|
||||
void movedown(params_t *prms)
|
||||
{
|
||||
if (prms->frog_pos->y != BOARD_N)
|
||||
{
|
||||
CLEAR_BACKPOS(prms->frog_pos->y, prms->frog_pos->x);
|
||||
prms->frog_pos->y += 2;
|
||||
}
|
||||
|
||||
check(prms);
|
||||
}
|
||||
|
||||
void moveright(params_t *prms)
|
||||
{
|
||||
if (prms->frog_pos->x != BOARD_M)
|
||||
{
|
||||
CLEAR_BACKPOS(prms->frog_pos->y, prms->frog_pos->x);
|
||||
prms->frog_pos->x++;
|
||||
}
|
||||
|
||||
check(prms);
|
||||
}
|
||||
|
||||
void moveleft(params_t *prms)
|
||||
{
|
||||
if (prms->frog_pos->x != 1)
|
||||
{
|
||||
CLEAR_BACKPOS(prms->frog_pos->y, prms->frog_pos->x);
|
||||
prms->frog_pos->x--;
|
||||
}
|
||||
|
||||
check(prms);
|
||||
}
|
||||
|
||||
void reach(params_t *prms)
|
||||
{
|
||||
prms->stats->score += 1;
|
||||
add_proggress(prms->map);
|
||||
if (check_level_compl(prms->map))
|
||||
{
|
||||
prms->stats->level++;
|
||||
prms->stats->speed++;
|
||||
*prms->state = SPAWN;
|
||||
}
|
||||
else
|
||||
{
|
||||
frogpos_init(prms->frog_pos);
|
||||
print_finished(prms->map);
|
||||
*prms->state = MOVING;
|
||||
}
|
||||
}
|
||||
|
||||
void collide(params_t *prms)
|
||||
{
|
||||
if (prms->stats->lives)
|
||||
{
|
||||
prms->stats->lives--;
|
||||
frogpos_init(prms->frog_pos);
|
||||
*prms->state = MOVING;
|
||||
}
|
||||
else
|
||||
*prms->state = GAMEOVER;
|
||||
}
|
||||
|
||||
void gameover(params_t *prms)
|
||||
{
|
||||
print_banner(prms->stats);
|
||||
}
|
||||
|
||||
void exitstate(params_t *prms)
|
||||
{
|
||||
*prms->state = EXIT_STATE;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue