OpenCores
URL https://opencores.org/ocsvn/connect-6/connect-6/trunk

Subversion Repositories connect-6

[/] [connect-6/] [trunk/] [XILINX/] [BUILD_SCC_SRCH/] [synth_src/] [threat_line.cpp] - Blame information for rev 17

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 sumanta.ch
 
2
/*
3
 
4
connectk -- a program to play the connect-k family of games
5
Copyright (C) 2007 Michael Levin
6
 
7
This program is free software; you can redistribute it and/or
8
modify it under the terms of the GNU General Public License
9
as published by the Free Software Foundation; either version 2
10
of the License, or (at your option) any later version.
11
 
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program; if not, write to the Free Software
19
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20
 
21
*/
22
 
23
//#include "config.h"
24
//#include <math.h>
25
//#include <glib->h>
26
//#include <iostream>
27
#include "./shared.h"
28
//#include "./q.hpp"
29
#include "pico.h"
30
//#include <stdio.h>
31
 
32
/* Bits per threat level */
33
#define BITS_PER_THREAT 6
34
 
35
 
36
//FIFO_INTERFACE(queue,AIMove);
37
static AIWEIGHT threat_bits(int threat, PIECE type, Board *b)
38
/* Bit pack the threat value */
39
{
40
        if (threat < 1)
41
                return 0;
42
 
43
        /* No extra value for building sequences over k - p unless it is
44
           enough to win */
45
        if (b->turn == type && connect_k - threat <= b->moves_left)
46
                threat = connect_k - place_p + 1;
47
        else if (threat >= connect_k - place_p)
48
                threat = connect_k - place_p - (type == b->turn);
49
 
50
        return 1 << ((threat - 1) * BITS_PER_THREAT);
51
}
52
 
53
static void threat_mark(int i, int threat, PIECE type,Board *b,Line *line)
54
{
55
        int j, index = 0;
56
 
57
        if (threat <= 0)
58
                return;
59
 
60
        /* No extra value for building sequences over k - p unless it is
61
           enough to win */
62
        if (b->turn == type && connect_k - threat <= b->moves_left)
63
                threat = connect_k - place_p + 1;
64
        else if (threat >= connect_k - place_p)
65
                threat = connect_k - place_p - (type == b->turn);
66
 
67
        /* Do not mark if this threat is dominated by a preceeding threat;
68
           Likewise supress any smaller threats */
69
        for (j = i; j >= 0 && j > i - connect_k; j--)
70
                if (line[j].threat[0] > threat)
71
                        return;
72
                else if (line[j].threat[0] < threat) {
73
                        line[j].threat[0] = 0;
74
                        line[j].threat[1] = 0;
75
                }
76
 
77
        /* Store up to two threats per tile in the line */
78
        if (line[i].threat[index])
79
                index++;
80
        line[i].threat[index] = threat;
81
        line[i].turn[index] = type;
82
}
83
 
84
int threat_window(int x, int y, int dx, int dy,
85
                         PIECE *ptype, int *pdouble,Board *b)
86
{
87
        int minimum, maximum, count = 0;
88
        PIECE p, type = PIECE_NONE;
89
 
90
        /* Check if this tile is empty */
91
        p = piece_at(b, x, y);
92
        if (!piece_empty(p))
93
                return 0;
94
 
95
        /* Push forward the maximum and find the window type */
96
        //#pragma unroll
97
        #pragma num_iterations(1,3,6)
98
        for (maximum = 1; maximum < connect_k; maximum++) {
99
                p = piece_at(b, x + dx * maximum, y + dy * maximum);
100
                if (p == PIECE_ERROR)
101
                        break;
102
                if (!piece_empty(p)) {
103
                        if (type == PIECE_NONE)
104
                                type = p;
105
                        else if (type != p)
106
                                break;
107
                        count++;
108
                }
109
        }
110
        maximum--;
111
 
112
        /* Try to push the entire window back */
113
        //#pragma unroll
114
        #pragma num_iterations(1,3,6)
115
        for (minimum = -1; minimum > -connect_k; minimum--) {
116
                p = piece_at(b, x + dx * minimum, y + dy * minimum);
117
                if (p == PIECE_ERROR || piece_empty(p))
118
                        break;
119
                if (type == PIECE_NONE)
120
                        type = p;
121
                else if (type != p)
122
                        break;
123
                if (maximum - minimum > connect_k - 1) {
124
                        p = piece_at(b, x + dx * maximum, y + dy * maximum);
125
                        if (p == type)
126
                                count--;
127
                        maximum--;
128
                }
129
                count++;
130
        }
131
        minimum++;
132
 
133
        /* Push back minimum if we haven't formed a complete window, this window
134
           can't be a double */
135
        if (maximum - minimum < connect_k - 1) {
136
        //#pragma unroll
137
        #pragma num_iterations(1,3,6)
138
                for (minimum--; minimum > maximum - connect_k; minimum--) {
139
                        p = piece_at(b, x + dx * minimum, y + dy * minimum);
140
                        if (p == PIECE_ERROR)
141
                                break;
142
                        if (!piece_empty(p)) {
143
                                if (type != p)
144
                                        break;
145
                                if (type == PIECE_NONE)
146
                                        type = p;
147
                                count++;
148
                        }
149
                }
150
                *pdouble = 0;
151
                minimum++;
152
        }
153
 
154
        *ptype = type;
155
        if (maximum - minimum >= connect_k - 1)
156
                return count;
157
        return 0;
158
}
159
 
160
/*static*/ AIWEIGHT threat_line(int x, int y, int dx, int dy,Board *b,Board *bwrite,int k,int loop_bound)
161
{
162
 
163
        //#pragma read_write_ports threat_counts.data combined 2
164
        //#pragma internal_blockram threat_counts
165
        //#pragma no_memory_analysis threat_counts
166
 
167
        //#pragma read_write_ports b.data combined 2
168
        //#pragma internal_blockram b
169
        //#pragma internal_blockram bwrite
170
        //#pragma read_write_ports b.data separate 1 readonly 2 writeonly
171
        //#pragma no_memory_analysis b
172
        /* This is the line of threats currently being processed */
173
        Line line[board_size]={{1},{2}};
174
        #pragma internal_fast line
175
        //#pragma multi_buffer line 2
176
        //#pragma no_memory_analysis line
177
        /* Running tally of threats for both players */
178
        //static int threat_counts[MAX_CONNECT_K + 1][2];
179
        threat_count_array threat_counts={{0}};
180
        #pragma internal_fast threat_counts
181
        //#pragma multi_buffer threat_counts 2
182
        //#pragma read_write_ports threat_counts.data combined 2
183
        //#pragma no_memory_analysis threat_counts
184
        static Board btmp;
185
        #pragma internal_blockram btmp
186
        //#pragma multi_buffer btmp 2
187
        if (k==1) board_copy(b, bwrite);
188
        //if (k==loop_bound) board_copy(&btmp, bwrite);
189
        int i;
190
        AIWEIGHT weight = 0;
191
        ///* Clear threat tallys */
192
        //for (i = 0; i < connect_k; i++) {
193
        //        threat_counts.data[i][0] = 1;
194
        //        threat_counts.data[i][1] = 1;
195
        //}
196
 
197
        /* Mark the maximum threat for each */
198
        for (i = 0; x >= 0 && x < board_size && y >= 0 && y < board_size; i++) {
199
                int count[2], tmp, double_threat = 1;
200
                PIECE type[2];
201
 
202
                count[0] = threat_window(x, y, dx, dy, type, &double_threat,bwrite);
203
                count[1] = threat_window(x, y, -dx, -dy, type + 1,
204
                                         &double_threat,bwrite);
205
                if (count[1] > count[0]) {
206
                        tmp = count[1];
207
                        count[1] = count[0];
208
                        count[0] = tmp;
209
                        tmp = type[1];
210
                        type[1] = type[0];
211
                        type[0] = tmp;
212
                }
213
                line[i].threat[0] = 0;
214
                line[i].threat[1] = 0;
215
                threat_mark(i, count[0], type[0],bwrite,&line[0]);
216
                if (double_threat)
217
                        threat_mark(i, count[1], type[1],bwrite,&line[0]);
218
                x += dx;
219
                y += dy;
220
        }
221
 
222
        /* Commit stored line values to the board */
223
        x -= dx;
224
        y -= dy;
225
        for (i--; x >= 0 && x < board_size && y >= 0 && y < board_size; i--) {
226
                AIWEIGHT bits[2];
227
                PIECE p;
228
 
229
                bits[0] = threat_bits(line[i].threat[0], line[i].turn[0],bwrite);
230
                bits[1] = threat_bits(line[i].threat[1], line[i].turn[1],bwrite);
231
                p = piece_at(bwrite, x, y);
232
                if (piece_empty(p) && line[i].threat[0]) {
233
                        threat_counts.data[line[i].threat[0]][line[i].turn[0] - 1]++;
234
                        if (line[i].threat[1])
235
                                threat_counts.data[line[i].threat[1]]
236
                                             [line[i].turn[1] - 1]++;
237
                        if (p >= PIECE_THREAT0)
238
                                place_threat(bwrite, x, y, p - PIECE_THREAT0 +
239
                                             bits[0] + bits[1]);
240
                        else
241
                                place_threat(bwrite, x, y, bits[0] + bits[1]);
242
                }
243
                if (bwrite->turn != line[i].turn[0])
244
                        bits[0] = -bits[0];
245
                if (bwrite->turn != line[i].turn[1])
246
                        bits[1] = -bits[1];
247
                weight += bits[0] + bits[1];
248
                x -= dx;
249
                y -= dy;
250
        }
251
        return weight;
252
}
253
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.