annotate board.c @ 10:4f6bf50dbc4a default tip

Detect the OS and configure build flags and libraries automatically
author Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
date Tue, 13 Sep 2016 18:19:44 +0200
parents aec74ae4d6e5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
1 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
2 * Copyright (C) 2014 Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
3 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
5 * a copy of this software and associated documentation files (the
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
6 * "Software"), to deal in the Software without restriction, including
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
7 * without limitation the rights to use, copy, modify, merge, publish,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
8 * distribute, sublicense, and/or sell copies of the Software, and to
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
9 * permit persons to whom the Software is furnished to do so, subject to
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
10 * the following conditions:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
11 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
12 * The above copyright notice and this permission notice shall be included
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
13 * in all copies or substantial portions of the Software.
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
14 *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
22 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
23
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
24 #include <stdlib.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
25 #include <unistd.h>
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
26 #include <curses.h> /* for OK, ERR */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
27
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
28 #include "board.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
29 #include "compat.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
30 #include "util.h"
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
31
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
32 struct stack_element {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
33 struct stack_element *next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
34 int x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
35 int y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
36 };
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
37
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
38 struct board_ctx *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
39 board_create(int height, int width, short colors)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
40 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
41 struct board_ctx *board;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
42
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
43 board = rantaiwarna_malloc(sizeof (struct board_ctx));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
44 board->elements = rantaiwarna_calloc((size_t)(width * height),
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
45 sizeof (short));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
46 board->seed = (uint32_t)getpid();
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
47 board->height = height;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
48 board->width = width;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
49 board->colors = colors;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
50 board->status = GAME_OVER;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
51 board->score = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
52 if (board_generate(board) == ERR) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
53 board_free(board);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
54 return (NULL);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
55 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
56
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
57 return (board);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
58 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
59
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
60 void
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
61 board_free(struct board_ctx *board)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
62 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
63 free(board->elements);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
64 free(board);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
65 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
66
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
67 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
68 board_check_status(struct board_ctx *board)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
69 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
70 int status = GAME_OVER | GAME_OVER_CLEARED;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
71 int y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
72 int x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
73
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
74 for (y = board->height - 1; y >= 0; y--) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
75 for (x = 0; x < board->width; x++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
76 if (board->elements[y * board->width + x] != 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
77 status &= ~GAME_OVER_CLEARED;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
78 if (((y - 1 >= 0) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
79 (board->elements[y * board->width + x] ==
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
80 board->elements[(y - 1) * board->width +
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
81 x])) ||
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
82 ((x + 1 < board->width) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
83 (board->elements[y * board->width + x] ==
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
84 (board->elements[y * board->width + x +
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
85 1])))) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
86 status &= ~GAME_OVER;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
87 goto out;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
88 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
89 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
90 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
91 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
92
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
93 out:
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
94 board->status = status;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
95 return (status);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
96 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
97
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
98 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
99 board_generate(struct board_ctx *board)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
100 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
101 int i;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
102 int j;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
103
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
104 /* make up to 1000 attempts to create a board that is playable */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
105 for (i = 0; i < 1000; i++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
106 for (j = 0; j < board->width * board->height; j++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
107 board->elements[j] =
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
108 (short)(rantaiwarna_rand(&board->seed) %
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
109 board->colors) + 1;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
110 }
4
aec74ae4d6e5 Fix the logic checking whether a generated board is playable
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents: 0
diff changeset
111 if (!(board_check_status(board) & GAME_OVER)) {
aec74ae4d6e5 Fix the logic checking whether a generated board is playable
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents: 0
diff changeset
112 break;
0
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
113 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
114 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
115
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
116 board->score = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
117
4
aec74ae4d6e5 Fix the logic checking whether a generated board is playable
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents: 0
diff changeset
118 return (!(board->status & GAME_OVER) ? OK : ERR);
0
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
119 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
120
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
121 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
122 board_compact(struct board_ctx *board)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
123 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
124 int changes = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
125 int x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
126 int y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
127 int top;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
128 int left;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
129
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
130 /* close vertical gaps iby moving elements down */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
131 for (x = 0; x < board->width; x++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
132 for (y = top = board->height - 1; y >= 0; y--) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
133 if (board->elements[y * board->width + x] != 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
134 board->elements[top * board->width + x] =
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
135 board->elements[y * board->width + x];
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
136 top--;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
137 changes++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
138 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
139 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
140 for (y = top; y >= 0; y--) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
141 board->elements[y * board->width + x] = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
142 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
143 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
144
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
145 /* close column gaps by moving columns to the left */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
146 for (x = left = 0; x < board->width; x++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
147 if (board->elements[(board->height - 1) * board->width + x] !=
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
148 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
149 if (x > left) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
150 for (y = 0; y < board->height; y++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
151 board->elements[y * board->width +
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
152 left] = board->elements[y *
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
153 board->width + x];
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
154 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
155 changes++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
156 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
157 left++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
158 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
159 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
160 for (x = left; x < board->width; x++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
161 for (y = 0; y < board->height; y++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
162 board->elements[y * board->width + x] = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
163 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
164 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
165
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
166 return (changes);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
167 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
168
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
169 int
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
170 board_remove_elements(struct board_ctx *board, int start_y, int start_x)
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
171 {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
172 int removed = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
173 int color;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
174 int x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
175 int y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
176 int west;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
177 int east;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
178 int n = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
179 int i;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
180 int save_x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
181 int save_y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
182 struct stack_element *stack_start;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
183 struct stack_element *stack_tmp;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
184 struct stack_element *stack_new;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
185
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
186 color = board->elements[start_y * board->width + start_x];
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
187 if (color == 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
188 return (0);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
189 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
190
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
191 stack_new = rantaiwarna_malloc(sizeof (struct stack_element));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
192 stack_new->next = NULL;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
193 stack_new->y = start_y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
194 stack_new->x = start_x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
195 stack_start = stack_new;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
196
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
197 while (stack_start != NULL) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
198 x = stack_start->x;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
199 y = stack_start->y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
200 stack_tmp = stack_start;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
201 stack_start = stack_start->next;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
202 free(stack_tmp);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
203
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
204 if (board->elements[y * board->width + x] != color) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
205 continue;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
206 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
207
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
208 for (west = x; (west - 1 >= 0) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
209 (board->elements[y * board->width + west - 1] == color);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
210 west--);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
211 for (east = x; (east + 1 < board->width) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
212 (board->elements[y * board->width + east + 1] == color);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
213 east++);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
214 for (i = west; i <= east; i++) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
215 /*
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
216 * only really start removing elements if there are
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
217 * more than two adjacent elements of the same color
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
218 */
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
219 n++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
220 if (n < 2) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
221 save_x = i;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
222 save_y = y;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
223 } else {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
224 if (n == 2) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
225 board->elements[save_y * board->width +
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
226 save_x] = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
227 removed++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
228 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
229 board->elements[y * board->width + i] = 0;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
230 removed++;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
231 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
232
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
233 if ((y - 1 >= 0) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
234 (board->elements[(y - 1) * board->width + i] ==
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
235 color)) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
236 stack_new = rantaiwarna_malloc(
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
237 sizeof (struct stack_element));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
238 stack_new->next = stack_start;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
239 stack_new->y = y - 1;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
240 stack_new->x = i;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
241 stack_start = stack_new;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
242 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
243 if ((y + 1 < board->height) &&
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
244 (board->elements[(y + 1) * board->width + i] ==
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
245 color)) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
246 stack_new = rantaiwarna_malloc(
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
247 sizeof (struct stack_element));
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
248 stack_new->next = stack_start;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
249 stack_new->y = y + 1;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
250 stack_new->x = i;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
251 stack_start = stack_new;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
252 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
253 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
254 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
255 if (removed > 0) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
256 board_compact(board);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
257 board->score += (removed - 1) * (removed - 1);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
258 board_check_status(board);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
259 if (board->status & GAME_OVER) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
260 if (board->status & GAME_OVER_CLEARED) {
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
261 board->score += 1000;
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
262 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
263 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
264 }
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
265
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
266 return (removed);
a9a7ad180c3b Initial revision
Guido Berhoerster <guido+rantaiwarna@berhoerster.name>
parents:
diff changeset
267 }