#ifndef INCLUDE_TICK_C #define INCLUDE_TICK_C #include "all.c" static int isRed(int cell) { return ( cell == RED || cell == RED_LEFT || cell == RED_RIGHT || cell == RED_UP || cell == RED_DOWN ); } static int isBlue(int cell) { return ( cell == BLUE || cell == BLUE_LEFT || cell == BLUE_RIGHT || cell == BLUE_UP || cell == BLUE_DOWN ); } static void tick(Game *game, Arena a) { State *lastState = new(&a, 1, State); xmemcpy(lastState, game, sizeof(State)); if (lastState->spawnerCount > 0) { game->state.spawnerCount = lastState->spawnerCount - 1; } for (int x = 0; x < GRIDWIDTH; x++) { for (int y = 0; y < GRIDHEIGHT; y++) { switch (lastState->grid[x + y * GRIDWIDTH]) { int reds, red; int blues, blue; case BLACK: reds = 0; if ( x < GRIDWIDTH - 1 && ( lastState->grid[x + 1 + y * GRIDWIDTH] == RED_LEFT || lastState->grid[x + 1 + y * GRIDWIDTH] == RED ) ) { reds++; if ( x < GRIDWIDTH - 2 && y > 0 && y < GRIDHEIGHT - 1 && lastState->grid[x + 2 + y * GRIDWIDTH] == YELLOW && lastState->grid[x + 1 + (y - 1) * GRIDWIDTH] == YELLOW && lastState->grid[x + 1 + (y + 1) * GRIDWIDTH] == YELLOW ) { red = RED_LEFT; } else { red = lastState->grid[x + 1 + y * GRIDWIDTH]; } } if ( x > 0 && ( lastState->grid[x - 1 + y * GRIDWIDTH] == RED_RIGHT || lastState->grid[x - 1 + y * GRIDWIDTH] == RED ) ) { reds++; if ( x > 1 && y > 0 && y < GRIDHEIGHT - 1 && lastState->grid[x - 2 + y * GRIDWIDTH] == YELLOW && lastState->grid[x - 1 + (y - 1) * GRIDWIDTH] == YELLOW && lastState->grid[x - 1 + (y + 1) * GRIDWIDTH] == YELLOW ) { red = RED_RIGHT; } else { red = lastState->grid[x - 1 + y * GRIDWIDTH]; } } if ( y > 0 && ( lastState->grid[x + (y - 1) * GRIDWIDTH] == RED_DOWN || lastState->grid[x + (y - 1) * GRIDWIDTH] == RED ) ) { reds++; if ( x > 0 && x < GRIDWIDTH - 1 && y > 1 && lastState->grid[x + (y - 2) * GRIDWIDTH] == YELLOW && lastState->grid[x - 1 + (y - 1) * GRIDWIDTH] == YELLOW && lastState->grid[x + 1 + (y - 1) * GRIDWIDTH] == YELLOW ) { red = RED_DOWN; } else { red = lastState->grid[x + (y - 1) * GRIDWIDTH]; } } if ( y < GRIDHEIGHT - 1 && ( lastState->grid[x + (y + 1) * GRIDWIDTH] == RED_UP || lastState->grid[x + (y + 1) * GRIDWIDTH] == RED ) ) { reds++; if ( x > 0 && x < GRIDWIDTH - 1 && y < GRIDHEIGHT - 2 && lastState->grid[x + (y + 2) * GRIDWIDTH] == YELLOW && lastState->grid[x - 1 + (y + 1) * GRIDWIDTH] == YELLOW && lastState->grid[x + 1 + (y + 1) * GRIDWIDTH] == YELLOW ) { red = RED_UP; } else { red = lastState->grid[x + (y + 1) * GRIDWIDTH]; } } if (reds == 1) { game->state.grid[x + y * GRIDWIDTH] = red; } else if (reds >= 2) { game->state.grid[x + y * GRIDWIDTH] = RED; } break; case RED: game->state.grid[x + y * GRIDWIDTH] = YELLOW; break; case RED_LEFT: if ( x > 0 && lastState->grid[x - 1 + y * GRIDWIDTH] == BLACK ) { game->state.grid[x + y * GRIDWIDTH] = YELLOW; } else { game->state.grid[x + y * GRIDWIDTH] = RED_UP; } break; case RED_RIGHT: if ( x < GRIDWIDTH - 1 && lastState->grid[x + 1 + y * GRIDWIDTH] == BLACK ) { game->state.grid[x + y * GRIDWIDTH] = YELLOW; } else { game->state.grid[x + y * GRIDWIDTH] = RED_DOWN; } break; case RED_UP: if ( y > 0 && lastState->grid[x + (y - 1) * GRIDWIDTH] == BLACK ) { game->state.grid[x + y * GRIDWIDTH] = YELLOW; } else { game->state.grid[x + y * GRIDWIDTH] = RED_RIGHT; } break; case RED_DOWN: if ( y < GRIDHEIGHT - 1 && lastState->grid[x + (y + 1) * GRIDWIDTH] == BLACK ) { game->state.grid[x + y * GRIDWIDTH] = YELLOW; } else { game->state.grid[x + y * GRIDWIDTH] = RED_LEFT; } break; case YELLOW: if ( (x > 0 && lastState->grid[x - 1 + y * GRIDWIDTH] == BLUE_RIGHT) || (x < GRIDWIDTH - 1 && lastState->grid[x + 1 + y * GRIDWIDTH] == BLUE_LEFT) || (y > 0 && lastState->grid[x + (y - 1) * GRIDWIDTH] == BLUE_DOWN) || (y < GRIDHEIGHT - 1 && lastState->grid[x + (y + 1) * GRIDWIDTH] == BLUE_UP) ) { game->state.grid[x + y * GRIDWIDTH] = RED; } else { game->state.grid[x + y * GRIDWIDTH] = BLACK; } break; case BLUE: // Win condition if (game->state.goalx == x && game->state.goaly == y) { if (!game->state.need9) { game->state.levelComplete = 1; } else { if (game->state.blues < 9) { game->state.blues++; if (game->state.blues == 9) { game->state.levelComplete = 1; } } } game->state.grid[x + y * GRIDWIDTH] = EMPTY; } blues = 0; if ( x > 0 && ( lastState->grid[x - 1 + y * GRIDWIDTH] == RED || lastState->grid[x - 1 + y * GRIDWIDTH] == RED_LEFT || lastState->grid[x - 1 + y * GRIDWIDTH] == RED_RIGHT || lastState->grid[x - 1 + y * GRIDWIDTH] == RED_DOWN || lastState->grid[x - 1 + y * GRIDWIDTH] == RED_UP ) ) { blues++; blue = BLUE_RIGHT; } if ( x < GRIDWIDTH - 1 && ( lastState->grid[x + 1 + y * GRIDWIDTH] == RED || lastState->grid[x + 1 + y * GRIDWIDTH] == RED_LEFT || lastState->grid[x + 1 + y * GRIDWIDTH] == RED_RIGHT || lastState->grid[x + 1 + y * GRIDWIDTH] == RED_DOWN || lastState->grid[x + 1 + y * GRIDWIDTH] == RED_UP ) ) { blues++; blue = BLUE_LEFT; } if ( y > 0 && ( lastState->grid[x + (y - 1) * GRIDWIDTH] == RED || lastState->grid[x + (y - 1) * GRIDWIDTH] == RED_LEFT || lastState->grid[x + (y - 1) * GRIDWIDTH] == RED_RIGHT || lastState->grid[x + (y - 1) * GRIDWIDTH] == RED_DOWN || lastState->grid[x + (y - 1) * GRIDWIDTH] == RED_UP ) ) { blues++; blue = BLUE_DOWN; } if ( y < GRIDHEIGHT - 1 && ( lastState->grid[x + (y + 1) * GRIDWIDTH] == RED || lastState->grid[x + (y + 1) * GRIDWIDTH] == RED_LEFT || lastState->grid[x + (y + 1) * GRIDWIDTH] == RED_RIGHT || lastState->grid[x + (y + 1) * GRIDWIDTH] == RED_DOWN || lastState->grid[x + (y + 1) * GRIDWIDTH] == RED_UP ) ) { blues++; blue = BLUE_UP; } if (blues == 1) { game->state.grid[x + y * GRIDWIDTH] = blue; } break; case BLUE_LEFT: if ( (x > 0 && isRed(lastState->grid[x - 1 + y * GRIDWIDTH])) || // (x < GRIDWIDTH - 1 && isRed(lastState->grid[x + 1 + y * GRIDWIDTH])) || (y > 0 && isRed(lastState->grid[x + (y - 1) * GRIDWIDTH])) || (y < GRIDHEIGHT - 1 && isRed(lastState->grid[x + (y + 1) * GRIDWIDTH])) ) { game->state.grid[x + y * GRIDWIDTH] = BLUE; } else if ( x > 0 && lastState->grid[x - 1 + y * GRIDWIDTH] == EMPTY ) { game->state.grid[x + y * GRIDWIDTH] = EMPTY; } else { game->state.grid[x + y * GRIDWIDTH] = BLUE; } break; case BLUE_RIGHT: if ( // (x > 0 && isRed(lastState->grid[x - 1 + y * GRIDWIDTH])) || (x < GRIDWIDTH - 1 && isRed(lastState->grid[x + 1 + y * GRIDWIDTH])) || (y > 0 && isRed(lastState->grid[x + (y - 1) * GRIDWIDTH])) || (y < GRIDHEIGHT - 1 && isRed(lastState->grid[x + (y + 1) * GRIDWIDTH])) ) { game->state.grid[x + y * GRIDWIDTH] = BLUE; } else if ( x < GRIDWIDTH - 1 && lastState->grid[x + 1 + y * GRIDWIDTH] == EMPTY ) { game->state.grid[x + y * GRIDWIDTH] = EMPTY; } else { game->state.grid[x + y * GRIDWIDTH] = BLUE; } break; case BLUE_UP: if ( (x > 0 && isRed(lastState->grid[x - 1 + y * GRIDWIDTH])) || (x < GRIDWIDTH - 1 && isRed(lastState->grid[x + 1 + y * GRIDWIDTH])) || (y > 0 && isRed(lastState->grid[x + (y - 1) * GRIDWIDTH]))// || // (y < GRIDHEIGHT - 1 && isRed(lastState->grid[x + (y + 1) * GRIDWIDTH])) ) { game->state.grid[x + y * GRIDWIDTH] = BLUE; } else if ( y > 0 && lastState->grid[x + (y - 1) * GRIDWIDTH] == EMPTY ) { game->state.grid[x + y * GRIDWIDTH] = EMPTY; } else { game->state.grid[x + y * GRIDWIDTH] = BLUE; } break; case BLUE_DOWN: if ( (x > 0 && isRed(lastState->grid[x - 1 + y * GRIDWIDTH])) || (x < GRIDWIDTH - 1 && isRed(lastState->grid[x + 1 + y * GRIDWIDTH])) || // (y > 0 && isRed(lastState->grid[x + (y - 1) * GRIDWIDTH])) || (y < GRIDHEIGHT - 1 && isRed(lastState->grid[x + (y + 1) * GRIDWIDTH])) ) { game->state.grid[x + y * GRIDWIDTH] = BLUE; } else if ( y < GRIDHEIGHT - 1 && lastState->grid[x + (y + 1) * GRIDWIDTH] == EMPTY ) { game->state.grid[x + y * GRIDWIDTH] = EMPTY; } else { game->state.grid[x + y * GRIDWIDTH] = BLUE; } break; case EMPTY: blues = 0; if ( x > 0 && lastState->grid[x - 1 + y * GRIDWIDTH] == BLUE_RIGHT ) { blues++; blue = BLUE_RIGHT; } if ( x < GRIDWIDTH - 1 && lastState->grid[x + 1 + y * GRIDWIDTH] == BLUE_LEFT ) { blues++; blue = BLUE_LEFT; } if ( y > 0 && lastState->grid[x + (y - 1) * GRIDWIDTH] == BLUE_DOWN ) { blues++; blue = BLUE_DOWN; } if ( y < GRIDHEIGHT - 1 && lastState->grid[x + (y + 1) * GRIDWIDTH] == BLUE_UP ) { blues++; blue = BLUE_UP; } if (blues == 1) { game->state.grid[x + y * GRIDWIDTH] = blue; } else if (blues >= 2) { game->state.grid[x + y * GRIDWIDTH] = BLUE; } // Spawner if ( game->state.spawnerx != 0 && game->state.spawnery != 0 && game->state.grid[x + y * GRIDWIDTH] == EMPTY && x == game->state.spawnerx && y == game->state.spawnery && lastState->spawnerCount == 0 ) { game->state.grid[x + y * GRIDWIDTH] = BLUE; game->state.spawnerCount = levels[game->state.currentLevel].spawnRate; } break; } } } } #endif // INCLUDE_TICK_C