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

Subversion Repositories connect-6

[/] [connect-6/] [trunk/] [CONNECTK/] [connectk-2.0/] [src/] [ai/] [window.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 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 <string.h>
25
#include <glib.h>
26
#include "../shared.h"
27
 
28
static int window_dir(const Board *b, BCOORD x, BCOORD y, PIECE type,
29
                      int dx, int dy, int *length, int *count)
30
{
31
        int i, j, min_i, max_i, min_block = 0, max_block = 0, max = 0;
32
        PIECE p;
33
 
34
        if (!dx && !dy)
35
                return 0;
36
 
37
        /* Find the lowest index i along our diagonal that is valid and is
38
           still a window containing (x, y) and count the number of pieces
39
           inside */
40
        for (i = 0; i > -connect_k; i--) {
41
                p = piece_at(b, x + dx * i, y + dy * i);
42
                if (p != type && p != PIECE_NONE) {
43
                        min_block = 1;
44
                        break;
45
                }
46
        }
47
        min_i = max_i = ++i;
48
        for (j = i; j < i + connect_k; j++) {
49
                p = piece_at(b, x + dx * j, y + dy *j);
50
                if (p == type)
51
                        max++;
52
                else if (p != PIECE_NONE)
53
                        return 0;
54
        }
55
 
56
        /* Slide out window along and find the smallest and largest maximum
57
           count positions */
58
        j = max;
59
        for (; i < 0; i++) {
60
                p = piece_at(b, x + dx * i, y + dy * i);
61
                if (p == type)
62
                        j--;
63
                p = piece_at(b, x + dx * (i + connect_k),
64
                             y + dy * (i + connect_k));
65
                if (p == type)
66
                        j++;
67
                else if (p != PIECE_NONE) {
68
                        max_block = 1;
69
                        break;
70
                }
71
                if (j == max)
72
                        max_i = i + 1;
73
                else if (j > max) {
74
                        max = j;
75
                        min_i = max_i = i + 1;
76
                }
77
        }
78
 
79
        /* Check if we have blocked multiple threats with this move */
80
        *count = 1;
81
        if (min_block || min_i > -connect_k + 1 ||
82
            ((p = piece_at(b, x - dx * connect_k, y - dy * connect_k)) !=
83
              type && p != PIECE_NONE))
84
                for (i = min_i; i < max_i; i++) {
85
                        p = piece_at(b, x + dx * i, y + dy * i);
86
                        if (p == PIECE_NONE)
87
                                (*count)++;
88
                        else if (p == PIECE_ERROR)
89
                                break;
90
                }
91
        if (max_block || max_i < 0 ||
92
            ((p = piece_at(b, x + dx * connect_k, y + dy * connect_k)) !=
93
             type && p != PIECE_NONE))
94
                for (i = min_i + connect_k; i < max_i + connect_k; i++) {
95
                        p = piece_at(b, x + dx * i, y + dy * i);
96
                        if (p == PIECE_NONE)
97
                                (*count)++;
98
                        else if (p == PIECE_ERROR)
99
                                break;
100
                }
101
 
102
        *length = max;
103
        return 1;
104
}
105
 
106
static AIWEIGHT window(const Board *b, BCOORD x, BCOORD y, PIECE turn)
107
{
108
        int lines[MAX_CONNECT_K], xs[] = {1, 1, 0, -1}, ys[] = {0, 1, 1, 1}, i;
109
        AIWEIGHT weight;
110
        PIECE type;
111
 
112
        memset(lines, 0, sizeof (lines));
113
        type = piece_at(b, x, y);
114
        if (type != PIECE_NONE)
115
                return AIW_NONE;
116
        for (i = 0; i < 4; i++) {
117
                int length, count;
118
 
119
                if (!window_dir(b, x, y, turn, xs[i], ys[i], &length, &count))
120
                        continue;
121
                lines[length] += count;
122
        }
123
 
124
        /* Bit pack the weight */
125
        weight = AIW_NONE;
126
        for (i = 1; i < connect_k; i++)
127
                weight += lines[i] << ((i - 1) * 6);
128
        return weight;
129
}
130
 
131
AIMoves *ai_windows(const Board *b)
132
{
133
        AIMoves *moves;
134
        AIMove move;
135
        PIECE opp = other_player(b->turn);
136
 
137
        moves = aimoves_new();
138
        moves->utility = AIW_NONE;
139
        for (move.y = 0; move.y < board_size; move.y++)
140
                for (move.x = 0; move.x < board_size; move.x++) {
141
                        move.weight = window(b, move.x, move.y, opp);
142
                        if (move.weight > AIW_NONE)
143
                                aimoves_append(moves, &move);
144
                }
145
        return moves;
146
}

powered by: WebSVN 2.1.0

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