📄 board.c
字号:
/*
** board.c
**
** Written by Peter Sutton - October 2004
**
** Board data is stored in an array of rowtype (which is wide enough
** a bit for each column). The bits of the rowtype
** represent whether that square is occupied or not (a 1 indicates
** occupied).
*/
#include "board.h"
#include "display.h"
#include "score.h"
#include "snake.h"
#include <stdio.h>
#include <stdlib.h>
/* Need stdlib for rand() - random number generation */
/*
** Global variables.
** food_positions records the (x,y) positions of each food item.
**
*/
rowtype board[BOARD_ROWS];
posn_type food_positions [MAX_FOOD];
int8_t num_food_items;
/*
** Initialise board - initial snake and some food
*/
void init_board(void) {
int8_t i;
num_food_items = 0;
/* Every block on the board should be cleared
*/
for(i=0; i < BOARD_ROWS; i++) {
board[i] = 0;
}
/* Cause the snake to be reset
*/
init_snake();
/* Add some food */
add_food_items(3);
/* Initialise the score to zero
*/
init_score();
}
/*
** Add/remove a block of the snake to the board at
** the given (x,y) position.
*/
void update_snake_block(int8_t x, int8_t y, int8_t add) {
rowtype mask;
int8_t bitposn;
/* Work out the bit position from the X value. The y
** value corresponds to the row number;
*/
bitposn = BOARD_WIDTH - 1 - x;
if(add) {
/* We're setting a bit, so we need an OR mask
** - all bits being 0 except the given position
*/
mask = 1<<bitposn;
board[y] |= mask;
display_snake_at(x,y);
} else {
/* We're clearing a bit, so we need an AND mask
** - all bits being 1 except the given position
*/
mask = ~(1<<bitposn);
board[y] &= mask;
display_blank_at(x,y);
}
}
int8_t is_off_board(int8_t x, int8_t y) {
if(x < 0 || x >= BOARD_WIDTH) {
return 1;
}
if(y < 0 || y >= BOARD_ROWS) {
return 1;
}
return 0;
}
/*
** Returns true if the snake is occupying
** the given position. (The position MUST be
** on the board.)
*/
int8_t is_snake_at(int8_t x, int8_t y) {
int8_t bitposn;
rowtype mask;
bitposn = BOARD_WIDTH - 1 - x;
mask = 1 << bitposn;
/* Check if the given bit of row y is 1. This
** will be non-zero (true) if the relevant bit
** board[y] is 1.
*/
if(board[y] & mask) {
return 1;
} else {
return 0;
}
}
int8_t food_at(int8_t x, int8_t y) {
int8_t i;
for(i=0; i < num_food_items; i++) {
if(food_positions[i].x == x &&
food_positions[i].y == y) {
/* Food found at this position */
return i;
}
}
/* No food found at the given position */
return -1;
}
/* Attempt to add randomly positioned food items. Returns
** the number of items actually positioned. (We may place
** fewer than the number requested because (a) we ran out
** of space to store them, or (b) we can't find space on
** the board for them.)
*/
int8_t add_food_items(int8_t num) {
/* Generate random positions until we get one
** at which there is no snake and no existing
** food.
*/
int8_t x, y, i, attempts;
for(i=0; i < num; i++) {
/* First check that we have space in our list
** of food items to hold another one. If not,
** just return.
*/
if(num_food_items >= MAX_FOOD) {
/* Number we've managed to add is i */
return i;
}
/* Make some attempts to randomly position
** some food. (We don't try forever - just
** in case the board is filled.)
*/
attempts = 0;
do {
x = rand() % BOARD_WIDTH;
y = rand() % BOARD_ROWS;
attempts++;
} while(attempts < 100 &&
(is_snake_at(x,y) || food_at(x,y) != -1));
if(attempts >= 100) {
/* We tried 100 times to generate a random position
** but they were all occupied.
*/
return i;
}
/* Now have an x,y position where we can put
** food
*/
food_positions[num_food_items].x = x;
food_positions[num_food_items].y = y;
num_food_items++;
display_food_at(x,y);
}
return num;
}
/*
** Remove the food item from our list of food
*/
void consume_food(int8_t foodID) {
int8_t i;
if(foodID < 0 || foodID >= num_food_items) {
/* Invalid foodID */
return;
}
/*
** If there is not a snake at this location, remove
** the food from the display.
*/
if(!is_snake_at(food_positions[foodID].x,
food_positions[foodID].y)) {
display_blank_at(food_positions[foodID].x,
food_positions[foodID].y);
}
/* Shuffle our list of food items along */
for(i=foodID+1; i <num_food_items; i++) {
food_positions[i-1] = food_positions[i];
}
num_food_items--;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -