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

Subversion Repositories connect-6

[/] [connect-6/] [trunk/] [CONNECT6_CMDLINE/] [connect6_synth.cpp] - Blame information for rev 5

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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