⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 board.c

📁 snake game in avr snake game in avr
💻 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 + -