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

Subversion Repositories connect-6

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 sumanta.ch
/*
2
    connect6.cpp
3
    June 9, 2011
4
    This file contains the game AI
5
    By Kevin Nam
6
 
7
*/
8
 
9
#include <time.h>
10
#include <stdlib.h>
11
 
12
#include "util.h"
13
#include "connect6.h"
14
 
15
// Subtract this many points for moves at the edges.
16
#define EDGEPENALTY 5
17
 
18
using namespace std;
19
 
20
/*  The cost function simply counts all of the consecutive stones of same colour in
21
    every direction from the spot for which the points is being calculated.
22
 
23
    Ex:
24
 
25
      .DDLL
26
      .DLDD
27
      DXDDD
28
      ...D.
29
 
30
    Above, X is the spot being calculated.
31
    The points would be 2 (above) + 2(topright) + 3(right) + 1 (left) = 8.
32
    It treats opponent's stones and own stones with equal weighting.
33
 
34
    Return 0 if the spot y,x is already taken, else return the calculated value
35
 
36
*/
37
int calculatepoints(char board[][19], int y, int x, char colour){
38
    int pts = 0, tempx = x, tempy = y, tcount = 0,bcount = 0;
39
    int lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0;
40
    char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0;
41
 
42
    if (board[y][x] != 0)
43
        return 0;
44
 
45
    // scan column above
46
    if (y > 0){
47
        tempy = y-1;
48
        tempx = x;
49
        tcolour = board[tempy][tempx];
50
        while (1){
51
            if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break;
52
            tcount++;
53
            if (tempy == 0) break;
54
            tempy--;
55
        }
56
    }
57
    // scan column below
58
    if (y < 18){
59
        tempy = y+1;
60
        tempx = x;
61
        bcolour = board[tempy][tempx];
62
        while (1){
63
            if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break;
64
            bcount++;
65
            if (tempy == 18) break;
66
            tempy++;
67
        }
68
    }
69
    // scan row to left
70
    if (x > 0){
71
        tempy = y;
72
        tempx = x-1;
73
        lcolour = board[tempy][tempx];
74
        while (1){
75
            if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break;
76
            lcount++;
77
            if (tempx == 0) break;
78
            tempx--;
79
        }
80
    }
81
    // scan row to right
82
    if (x < 18){
83
        tempy = y;
84
        tempx = x+1;
85
        rcolour = board[tempy][tempx];
86
        while (1){
87
            if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break;
88
            rcount++;
89
            if (tempx == 18) break;
90
            tempx++;
91
        }
92
    }
93
    // scan diagonal topleft
94
    if (x > 0 && y > 0){
95
        tempy = y-1;
96
        tempx = x-1;
97
        tlcolour = board[tempy][tempx];
98
        while (1){
99
            if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break;
100
            tlcount++;
101
            if (tempx == 0 || tempy == 0) break;
102
            tempx--;
103
            tempy--;
104
        }
105
    }
106
    // scan diagonal bottomright
107
    if (x < 18 && y < 18){
108
        tempy = y+1;
109
        tempx = x+1;
110
        brcolour = board[tempy][tempx];
111
        while (1){
112
            if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break;
113
            brcount++;
114
            if (tempx == 18 || tempy == 18) break;
115
            tempx++;
116
            tempy++;
117
        }
118
    }
119
    // scan diagonal topright
120
    if (x < 18 && y > 0){
121
        tempy = y-1;
122
        tempx = x+1;
123
        trcolour = board[tempy][tempx];
124
        while (1){
125
            if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break;
126
            trcount++;
127
            if (tempx == 18 || tempy == 0) break;
128
            tempx++;
129
            tempy--;
130
        }
131
    }
132
    // scan diagonal bottomleft
133
    if (y < 18 && x > 0){
134
        tempy = y+1;
135
        tempx = x-1;
136
        blcolour = board[tempy][tempx];
137
        while (1){
138
            if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break;
139
            blcount++;
140
            if (tempy == 18 || tempx == 0) break;
141
            tempy++;
142
            tempx--;
143
        }
144
    }
145
 
146
    /// Now calculate the points
147
    // Check if this is a winning move. Priority #1.
148
    if ((tcount >= 5 && tcolour == colour) ||
149
        (bcount >= 5 && bcolour == colour) ||
150
        (lcount >= 5 && lcolour == colour) ||
151
        (rcount >= 5 && rcolour == colour) ||
152
        (tlcount >= 5 && tlcolour == colour) ||
153
        (trcount >= 5 && trcolour == colour) ||
154
        (brcount >= 5 && brcolour == colour) ||
155
        (blcount >= 5 && blcolour == colour) ||
156
        (tcount + bcount >= 5 && tcolour == colour && bcolour == colour) ||
157
        (lcount + rcount >= 5 && lcolour == colour && rcolour == colour) ||
158
        (tlcount + brcount >= 5 && tlcolour == colour && brcolour == colour) ||
159
        (trcount + blcount >= 5 && trcolour == colour && blcolour == colour))
160
        return 1000;
161
 
162
    // Check if this move can stop opponent from winning. This move is priority #2.
163
    if ((tcount >= 4 && tcolour != colour) ||
164
        (bcount >= 4 && bcolour != colour) ||
165
        (lcount >= 4 && lcolour != colour) ||
166
        (rcount >= 4 && rcolour != colour) ||
167
        (tlcount >= 4 && tlcolour != colour) ||
168
        (trcount >= 4 && trcolour != colour) ||
169
        (brcount >= 4 && brcolour != colour) ||
170
        (blcount >= 4 && blcolour != colour) ||
171
        (tcount + bcount >= 4 && tcolour != colour && bcolour != colour) ||
172
        (lcount + rcount >= 4 && lcolour != colour && rcolour != colour) ||
173
        (tlcount + brcount >= 4 && tlcolour != colour && brcolour != colour) ||
174
        (trcount + blcount >= 4 && trcolour != colour && blcolour != colour))
175
        return 500;
176
 
177
    // Else sum up the counts, use this as the points.
178
    pts = tcount + bcount + lcount + rcount + tlcount + trcount + blcount + brcount + 1;
179
    // If at an edge, lower the points
180
    if (x == 0 || x == 18 || y == 0 || y == 18){
181
        if (pts >= EDGEPENALTY)
182
            pts -= EDGEPENALTY;
183
        else
184
            pts = 0;
185
    }
186
    return pts;
187
}
188
 
189
/*
190
    The AI Function that calls the cost function for every spot on the board.
191
    It returns the location with the highest points. In the event of a tie, randomly decide.
192
    Input the board and the colour being played.
193
    Puts the move (in ASCII chars) inside move[4]. This is from [1 ... 19]
194
    Puts the move (in integers) in moveY and moveX. This is from [0 ... 18]
195
*/
196
int connect6ai(char board[][19], char colour, char move[4]){
197
    int x,y,highx = 0, highy = 0,currenthigh = 0, temp;
198
    srand(time(NULL));
199
#ifdef EMUL
200
    int highRandom =rand();
201
#else
202
    int highRandom =1;//rand();
203
#endif
204
    // Sweep the entire board with the cost function
205
    for (x = 0; x <= 18; x++){
206
        for (y = 0; y <= 18; y++){
207
 
208
            temp = calculatepoints(board,y,x, colour);
209
            if (temp > currenthigh){
210
                highx = x;
211
                highy = y;
212
                currenthigh = temp;
213
#ifdef EMUL
214
                highRandom =rand();
215
#else
216
                highRandom =1;//rand();
217
#endif
218
            }
219
            // If a tie happens, pseudo-randomly choose one between them
220
            if (temp == currenthigh && temp != 0){
221
#ifdef EMUL
222
                int tempRandom =rand();
223
#else
224
                int tempRandom =1;//rand();
225
#endif
226
                if (tempRandom > highRandom){
227
                    highx = x;
228
                    highy = y;
229
                    highRandom = tempRandom;
230
                }
231
            }
232
        }
233
    }
234
 
235
    // Modify the board based on current move.
236
    board[highy][highx] = colour;
237
 
238
    // Increment by 1 because indexing starts at 1.
239
    highy++;
240
    highx++;
241
 
242
    /// Convert the int coordinates to corresponding ASCII chars
243
    if (highy >= 10){
244
        move[0] = '1';
245
        highy -= 10;
246
    } else {
247
        move[0] = '0';
248
    }
249
    if      (highy == 0) move[1] = '0';
250
    else if (highy == 1) move[1] = '1';
251
    else if (highy == 2) move[1] = '2';
252
    else if (highy == 3) move[1] = '3';
253
    else if (highy == 4) move[1] = '4';
254
    else if (highy == 5) move[1] = '5';
255
    else if (highy == 6) move[1] = '6';
256
    else if (highy == 7) move[1] = '7';
257
    else if (highy == 8) move[1] = '8';
258
    else if (highy == 9) move[1] = '9';
259
 
260
    // Do same for x.
261
    if (highx >= 10){
262
        move[2] = '1';
263
        highx -= 10;
264
    } else {
265
        move[2] = '0';
266
    }
267
    if      (highx == 0) move[3] = '0';
268
    else if (highx == 1) move[3] = '1';
269
    else if (highx == 2) move[3] = '2';
270
    else if (highx == 3) move[3] = '3';
271
    else if (highx == 4) move[3] = '4';
272
    else if (highx == 5) move[3] = '5';
273
    else if (highx == 6) move[3] = '6';
274
    else if (highx == 7) move[3] = '7';
275
    else if (highx == 8) move[3] = '8';
276
    else if (highx == 9) move[3] = '9';
277
 
278
    return 0;
279
}
280
 
281
 
282
// scan board, return 'L' or 'D' for the winner, 'n' if no winner.
283
char check_for_win (char board[][19]){
284
    int y,x;
285
    for (y = 0; y < 19; y++){
286
        for (x = 0; x < 19; x++){
287
            if (board[y][x] == 0)
288
                continue;
289
 
290
            int tempx, tempy, tcount = 0,bcount = 0;
291
            int lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0;
292
            char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0;
293
 
294
            // scan column above
295
            if (y > 0){
296
                tempy = y;
297
                tempx = x;
298
                tcolour = board[tempy][tempx];
299
                while (1){
300
                    if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break;
301
                    tcount++;
302
                    if (tempy == 0) break;
303
                    tempy--;
304
                }
305
            }
306
            // scan column below
307
            if (y < 18){
308
                tempy = y+1;
309
                tempx = x;
310
                bcolour = board[tempy][tempx];
311
                while (1){
312
                    if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break;
313
                    bcount++;
314
                    if (tempy == 18) break;
315
                    tempy++;
316
                }
317
            }
318
 
319
            if (tcolour == bcolour && tcount + bcount >= 6) return tcolour;
320
 
321
            // scan row to left
322
            if (x > 0){
323
                tempy = y;
324
                tempx = x;
325
                lcolour = board[tempy][tempx];
326
                while (1){
327
                    if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break;
328
                    lcount++;
329
                    if (tempx == 0) break;
330
                    tempx--;
331
                }
332
            }
333
            // scan row to right
334
            if (x < 18){
335
                tempy = y;
336
                tempx = x+1;
337
                rcolour = board[tempy][tempx];
338
                while (1){
339
                    if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break;
340
                    rcount++;
341
                    if (tempx == 18) break;
342
                    tempx++;
343
                }
344
            }
345
 
346
            if (lcolour == rcolour && lcount + rcount >= 6) return lcolour;
347
 
348
            // scan diagonal topleft
349
            if (x > 0 && y > 0){
350
                tempy = y;
351
                tempx = x;
352
                tlcolour = board[tempy][tempx];
353
                while (1){
354
                    if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break;
355
                    tlcount++;
356
                    if (tempx == 0 || tempy == 0) break;
357
                    tempx--;
358
                    tempy--;
359
                }
360
            }
361
            // scan diagonal bottomright
362
            if (x < 18 && y < 18){
363
                tempy = y+1;
364
                tempx = x+1;
365
                brcolour = board[tempy][tempx];
366
                while (1){
367
                    if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break;
368
                    brcount++;
369
                    if (tempx == 18 || tempy == 18) break;
370
                    tempx++;
371
                    tempy++;
372
                }
373
            }
374
 
375
            if (tlcolour == brcolour && tlcount + brcount >= 6) return tlcolour;
376
 
377
            // scan diagonal topright
378
            if (x < 18 && y > 0){
379
                tempy = y;
380
                tempx = x;
381
                trcolour = board[tempy][tempx];
382
                while (1){
383
                    if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break;
384
                    trcount++;
385
                    if (tempx == 18 || tempy == 0) break;
386
                    tempx++;
387
                    tempy--;
388
                }
389
            }
390
            // scan diagonal bottomleft
391
            if (y < 18 && x > 0){
392
                tempy = y+1;
393
                tempx = x-1;
394
                blcolour = board[tempy][tempx];
395
                while (1){
396
                    if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break;
397
                    blcount++;
398
                    if (tempy == 18 || tempx == 0) break;
399
                    tempy++;
400
                    tempx--;
401
                }
402
            }
403
 
404
            if (trcolour == blcolour && trcount + blcount >= 6) return trcolour;
405
        }
406
    }
407
    // return 'n' for no victory
408
    return 'n';
409
}
410
 
411
// Check if the board is full
412
int check_board_full (char board[][19]){
413
    int y,x;
414
    // As soon as there is an empty intersection, return 0;
415
    for (y = 0; y < 19; y++)
416
        for (x = 0; x < 19; x++)
417
            if (board[y][x] == 0)
418
                return 0;
419
 
420
    // By now, swept entire board and all filled.
421
    return -1;
422
}
423
 
424
// Check if move y,x is valid. Here, y and x are [0 ... 18]
425
int check_move_validity (char board[][19],int y, int x){
426
    if (y < 0 || y > 18 || x < 0 || x > 18 || board[y][x] != 0){
427
        return -1;
428
    }
429
    return 0;
430
}
431
 
432
 
433
void print_board (char board[][19]){
434
    printf("  1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9");
435
    unsigned short x,y;
436
    for (x = 0; x <= 18; x++){
437
    printf("\n");
438
    printf("%d",x+1);
439
    if (x < 9) printf(" ");
440
        for (y = 0; y <= 18; y++){
441
            if (board[x][y] == 0)
442
                printf(".");
443
            else printf("%c",board[x][y]);
444
            printf(" ");
445
        }
446
 
447
    }
448
    printf("\n");
449
}
450
 
451
void print_board_file (char board[][19]){
452
char filename[12]="myboard.txt";
453
FILE *fp=fopen(filename,"w");
454
    fprintf(fp,"  1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9");
455
    unsigned short x,y;
456
    for (x = 0; x <= 18; x++){
457
    fprintf(fp,"\n");
458
    fprintf(fp,"%d",x+1);
459
    if (x < 9) fprintf(fp," ");
460
        for (y = 0; y <= 18; y++){
461
            if (board[x][y] == 0)
462
                fprintf(fp,".");
463
            else fprintf(fp,"%c",board[x][y]);
464
            fprintf(fp," ");
465
        }
466
 
467
    }
468
    fprintf(fp,"\n");
469
fclose(fp);
470
}

powered by: WebSVN 2.1.0

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