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

Subversion Repositories connect-6

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

Go to most recent revision | 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 <glib.h>
25
#include "../shared.h"
26
#include "../connectk.h"
27
 
28
/* FIXME: The AI thread function busy waits on Windows. For some reason, it fails to
29
   deadlock itself on mutex1! */
30
 
31
int ai_stop = 0;
32
 
33
static GMutex *ai_mutex1, *ai_mutex2;
34
static guint ai_done_source = 0;
35
static AIMove ai_move;
36
static GThread *ai_thread;
37
static int ai_halt = 0;
38
 
39
static gboolean ai_done(gpointer user_data)
40
{
41
        if (opt_debug_thread)
42
                g_debug("ai_done(): making AI move");
43
        make_move(ai_move.x, ai_move.y);
44
        return FALSE;
45
}
46
 
47
AIMoves *run_ai(Player *player)
48
{
49
        AIMoves *moves;
50
        AIFunc func;
51
 
52
        if (opt_debug_thread)
53
                g_debug("run_ai(): running AI function");
54
        ai_stop = FALSE;
55
        func = ai(player->ai)->func;
56
        if (!func)
57
                return NULL;
58
        moves = func(board);
59
        if (player->search)
60
                search(board, moves, player);
61
 
62
        ai_stop = FALSE;
63
        return moves;
64
}
65
 
66
static gpointer ai_thread_func(gpointer user_data)
67
{
68
        for (;;) {
69
                AIMoves *moves;
70
 
71
                if (opt_debug_thread)
72
                        g_debug("ai_thread_func(): locking mutex1");
73
                g_mutex_lock(ai_mutex1);
74
                if (opt_debug_thread)
75
                        g_debug("ai_thread_func(): mutex1 locked");
76
                if (ai_halt) {
77
                        ai_halt = FALSE;
78
                        g_mutex_unlock(ai_mutex1);
79
                        return NULL;
80
                }
81
                if (opt_debug_thread)
82
                        g_debug("ai_thread_func(): locking mutex2");
83
                g_mutex_lock(ai_mutex2);
84
                if (opt_debug_thread)
85
                        g_debug("ai_thread_func(): mutex2 locked");
86
                if (ai(players[board->turn].ai)->func && !opt_pause_ai &&
87
                    !board->won) {
88
                        ai_move.x = -1;
89
                        ai_move.y = -1;
90
                        moves = run_ai(players + board->turn);
91
 
92
                        /* Choose an adjacent move if the AI returns nothing */
93
                        if (!aimoves_choose(moves, &ai_move)) {
94
                                aimoves_free(moves);
95
                                moves = ai_adjacent(board);
96
                                aimoves_choose(moves, &ai_move);
97
                        }
98
 
99
                        /* Print the move list utility */
100
                        if (opt_print_u)
101
                                g_debug("AI %s utility %d (0x%x)",
102
                                        ai(players[board->turn].ai)->s_desc,
103
                                        moves->utility, moves->utility);
104
 
105
                        ai_done_source = g_timeout_add(0, ai_done, NULL);
106
                        aimoves_free(moves);
107
                }
108
                g_mutex_unlock(ai_mutex2);
109
                if (opt_debug_thread)
110
                        g_debug("ai_thread_func(): mutex2 unlocked");
111
                g_thread_yield();
112
        }
113
        return NULL;
114
}
115
 
116
void stop_ai(void)
117
{
118
        ai_stop = TRUE;
119
#ifndef NO_TRYLOCK
120
        if (opt_debug_thread)
121
                g_debug("stop_ai(): trylocking mutex1");
122
        g_mutex_trylock(ai_mutex1);
123
#endif
124
        if (opt_debug_thread)
125
                g_debug("stop_ai(): locking mutex2");
126
        g_mutex_lock(ai_mutex2);
127
        if (opt_debug_thread)
128
                g_debug("stop_ai(): mutex2 locked");
129
        if (ai_done_source) {
130
                g_source_remove(ai_done_source);
131
                ai_done_source = 0;
132
        }
133
        g_mutex_unlock(ai_mutex2);
134
        if (opt_debug_thread)
135
                g_debug("stop_ai(): mutex2 unlocked");
136
}
137
 
138
void start_ai(void)
139
{
140
        if (players[board->turn].ai == PLAYER_HUMAN)
141
                return;
142
 
143
#ifndef NO_TRYLOCK
144
        if (opt_debug_thread)
145
                g_debug("start_ai(): trylocking mutex1");
146
        g_mutex_trylock(ai_mutex1);
147
#endif
148
        g_mutex_unlock(ai_mutex1);
149
        if (opt_debug_thread)
150
                g_debug("stop_ai(): mutex1 unlocked");
151
}
152
 
153
void halt_ai_thread(void)
154
{
155
        if (opt_debug_thread)
156
                g_debug("halt_ai_thread(): unlocking mutex1, joining thread");
157
        ai_stop = TRUE;
158
        ai_halt = TRUE;
159
        g_mutex_unlock(ai_mutex1);
160
        g_thread_join(ai_thread);
161
        if (opt_debug_thread)
162
                g_debug("halt_ai_thread(): mutex1 unlocked");
163
}
164
 
165
void start_ai_thread(void)
166
{
167
        GError *error = NULL;
168
 
169
        g_thread_init(NULL);
170
        ai_mutex1 = g_mutex_new();
171
        ai_mutex2 = g_mutex_new();
172
        g_mutex_lock(ai_mutex1);
173
        if (opt_debug_thread)
174
                g_debug("start_ai_thread(): mutex1, mutex2 locked");
175
 
176
        ai_thread = g_thread_create_full(ai_thread_func, NULL, 0, TRUE, TRUE,
177
                                         G_THREAD_PRIORITY_NORMAL, &error);
178
        if (error)
179
                g_error("Failed to spawn AI thread");
180
}
181
 

powered by: WebSVN 2.1.0

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