OpenCores

Subversion Repositories connect-6

[/] [connect-6/] [trunk/] [BUILD_SCC/] [synth_src/] [state.cpp] - Rev 4

Go to most recent revision | Compare with Previous | Blame | View Log

 
/*
 
connectk -- a program to play the connect-k family of games
Copyright (C) 2007 Michael Levin
 
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
*/
 
//#include "config.h"
//#include <gtk/gtk.h>
//#include <glib/gprintf.h>
//#include <stdlib.h>
//#include <stdio.h>
//#include <string.h>
//#include <math.h>
#include "./shared.h"
//#include "connectk.h"
 
/*
 *      Allocation chain
 */
 
#define IA 1103515245u
#define IC 12345u
#define IM 2147483648u
#define CHECK_RAND
//moved the following declaration to connect6_threat
//static unsigned int current_random = 0;
 
//from vpr uti.c code
/* Portable random number generator defined below.  Taken from ANSI C by  *
 * K & R.  Not a great generator, but fast, and good enough for my needs. */
 
 
void my_srandom(int seed,unsigned int *current_random)
{
    *current_random = (unsigned int)seed;
}
 
 
int my_irand(int imax,unsigned int current_random)
{
 
///* Creates a random integer between 0 and imax, inclusive.  i.e. [0..imax] */
//
//    int ival;
//
///* current_random = (current_random * IA + IC) % IM; */
//    current_random = current_random * IA + IC;  /* Use overflow to wrap */
//    ival = current_random & (IM - 1);   /* Modulus */
//	//float not synthesizable
//    //ival = (int)((float)ival * (float)(imax + 0.999) / (float)IM);
//    ival = (int)(ival * (imax + 1) / IM);
//
//#ifdef CHECK_RAND
//    if((ival < 0) || (ival > imax))
//        {
//            //printf("Bad value in my_irand, imax = %d  ival = %d\n", imax,
//            //       ival);
//            //exit(1);
//        }
//#endif
//
//    return (ival);
return(0);
}
 
 
//static void achain_init(AllocChain *ac)
//{
//        static unsigned int ids;
//
//        ac->free = FALSE;
//        ac->id = ids++;
//}
//
//AllocChain *achain_new(AllocChain **root, AllocFunc afunc)
//{
//        AllocChain *ac;
//
//        if (!*root) {
//                *root = afunc(NULL);
//                achain_init(*root);
//                (*root)->next = NULL;
//                return *root;
//        }
//        ac = *root;
//        for (;;) {
//                if (ac->free) {
//                        afunc(ac);
//                        achain_init(ac);
//                        return ac;
//                }
//                if (!ac->next)
//                        break;
//                ac = ac->next;
//        }
//        ac->next = afunc(NULL);
//        achain_init(ac->next);
//        ac->next->next = NULL;
//        return ac->next;
//}
//
//void achain_free(AllocChain *ac)
//{
//        if (!ac)
//                return;
//        ac->free = TRUE;
//}
//
//void achain_copy(const AllocChain *src, AllocChain *dest, gsize mem)
//{
//        if (!src || !dest || !mem) {
//                g_warning("NULL argument(s) to achain_copy");
//                return;
//        }
//        memcpy((char*)dest + sizeof (AllocChain),
//               (char*)src + sizeof (AllocChain), mem - sizeof (AllocChain));
//}
//
//static void achain_dealloc(AllocChain **root, gsize mem)
//{
//        AllocChain *ac = *root, *ac_next;
//
//        while (ac) {
//                ac_next = ac->next;
//                g_slice_free1(mem, ac);
//                ac = ac_next;
//        }
//        *root = NULL;
//}
 
 
//      Move Arrays
 
 
//AllocChain *aimoves_root = NULL;
gsize aimoves_mem = 0;
 
//AllocChain *aimoves_alloc(AllocChain *ac)
//{
//        //if (!ac)
//        //        ac = (AllocChain*)g_slice_alloc(aimoves_mem);
//        //memset((char*)ac + sizeof (AllocChain), 0, sizeof (AIMoves) -
//        //       sizeof (AllocChain));
//        //return ac;
//}
 
void aimoves_add(AIMoves *moves, const AIMove *move)
{
        int i;
 
        i = aimoves_find(moves, move->x, move->y);
        if (i < 0) {
                if (moves->len >= board_size * board_size)
                        //g_warning("Attempted to add a move to a full AIMoves");
			//printf("Attempted to add a move to a full AIMoves");
			return;
                else
                        moves->data[moves->len++] = *move;
        } else
                moves->data[i].weight += move->weight;
}
 
void aimoves_append(AIMoves *moves, const AIMove *move)
{
        int i;
 
        if (move->x >= board_size || move->y >= board_size)
                return;
        for (i = 0; i < moves->len; i++) {
                AIMove *aim = moves->data + i;
 
                if (aim->x == move->x && aim->y == move->y) {
                        aim->weight = move->weight;
                        return;
                }
        }
        if (moves->len >= board_size * board_size) {
                //g_warning("Attempted to append a move to a full AIMoves");
                //printf("Attempted to append a move to a full AIMoves");
                return;
        }
        moves->data[moves->len++] = *move;
}
 
int aimoves_compare(const void *a, const void *b)
{
        return ((AIMove*)b)->weight - ((AIMove*)a)->weight;
}
 
int aimoves_choose(AIMoves *moves, AIMove *move)
{
	//#pragma read_write_ports moves.data combined 3
	//#pragma internal_blockram moves
	//#pragma no_memory_analysis moves
        int i = 0, top = 0;
	#pragma bitsize i 4
        if (!moves || !moves->len)
                return 0;
        aimoves_sort(moves);
        for (top = 0; top < moves->len &&
             moves->data[top].weight == moves->data[0].weight; top++);
        if (top)
                //i = my_irand(top,current_random);//g_random_int_range(0, top);
		i=0;
 
        *move = moves->data[i];
        return 1;
}
//
//void aimoves_crop(AIMoves *moves, unsigned int n)
//{
//        if (moves->len < n)
//                return;
//        aimoves_shuffle(moves);
//        aimoves_sort(moves);
//        moves->len = n;
//}
//
//void aimoves_concat(AIMoves *m1, const AIMoves *m2)
//{
//        gsize max_len = board_size * board_size, len;
//
//        len = m2->len;
//        if (m1->len + len > max_len)
//                len = max_len - m1->len;
//        memcpy(m1->data + len, m2->data, len * sizeof (AIMove));
//        m1->len += len;
//}
//
//AIMoves *aimoves_dup(const AIMoves *moves)
//{
//        AIMoves *dup;
//
//        if (!moves)
//                return NULL;
//        dup = aimoves_new();
//        dup->len = moves->len;
//        memcpy(dup->data, moves->data, moves->len * sizeof (AIMove));
//        return dup;
//}
//
int aimoves_find(const AIMoves *moves, BCOORD x, BCOORD y)
{
        int i;
 
        if (moves)
                for (i = 0; i < moves->len; i++) {
                        const AIMove *aim = moves->data + i;
 
                        if (aim->x == x && aim->y == y)
                                return i;
                }
        return -1;
}
//
//void aimoves_range(AIMoves *moves, AIWEIGHT *min, AIWEIGHT *max)
//{
//        int i;
//
//        *min = AIW_MAX;
//        *max = AIW_MIN;
//        for (i = 0; i < moves->len; i++) {
//                if (moves->data[i].weight > *max)
//                        *max = moves->data[i].weight;
//                if (moves->data[i].weight < *min)
//                        *min = moves->data[i].weight;
//        }
//}
//
//void aimoves_merge(AIMoves *m1, const AIMoves *m2)
//{
//        int len = m1->len, i, j;
//
//        for (i = 0; i < m2->len; i++)
//                for (j = 0;; j++) {
//                        if (j >= len) {
//                                aimoves_append(m1, m2->data + i);
//                                break;
//                        }
//                        if (m1->data[j].x == m2->data[i].x &&
//                            m1->data[j].y == m2->data[i].y) {
//                                if (m2->data[i].weight > m1->data[j].weight)
//                                        m1->data[j].weight = m2->data[i].weight;
//                                break;
//                        }
//                }
//}
//
//char *aimove_to_string(const AIMove *aim)
//{
//        static char buffer[32];
//
//        g_snprintf(buffer, sizeof (buffer), "%s (%s)",
//                   bcoords_to_string(aim->x, aim->y),
//                   aiw_to_string(aim->weight));
//        return buffer;
//}
//
//void aimoves_print(const AIMoves *moves)
//{
//        int i;
//
//        if (!moves || !moves->len) {
//                g_print("(empty)");
//                return;
//        }
//        for (i = 0; i < moves->len; i++) {
//                const AIMove *aim = moves->data + i;
//
//                if (i)
//                        g_print(", ");
//                g_print("%s", aimove_to_string(aim));
//        }
//}
//
//void aimoves_remove_index_fast(AIMoves *moves, int i)
//{
//        if (moves->len > i)
//                moves->data[i] = moves->data[moves->len - 1];
//        moves->len--;
//}
//
//void aimoves_remove(AIMoves *moves, BCOORD x, BCOORD y)
//{
//        int i;
//
//        for (i = 0; i < moves->len; i++) {
//                AIMove *aim = moves->data + i;
//
//                if (aim->x == x && aim->y == y) {
//                        aimoves_remove_index_fast(moves, i);
//                        return;
//                }
//        }
//}
//
void aimoves_shuffle(AIMoves *moves,unsigned int current_random)
{
//        int i;
//
//        if (opt_det_ai)
//                return;
//
//        /* Fisher-Yates shuffle */
//        for (i = 0; i < moves->len; i++) {
//                int j;
//
//                j = my_irand(moves->len,current_random);//g_random_int_range(i, moves->len);
//                if (i != j) {
//                        AIMove tmp;
//
//                        tmp = moves->data[i];
//                        moves->data[i] = moves->data[j];
//                        moves->data[j] = tmp;
//                }
//        }
return;
}
 
 
//taken from http://cprogramminglanguage.net/c-bubble-sort-source-code.aspx
void swap(AIMove  *x,AIMove *y)
{
   AIMove temp;
   temp = *x;
   *x = *y;
   *y = temp;
}
void bublesort(AIMove *list, int n)
{
   int i,j;
   for(i=0;i<(n-1);i++)
      for(j=0;j<(n-(i+1));j++)
             if(list[j].weight < list[j+1].weight)
                    swap(&list[j],&list[j+1]);
}
//taken from http://cprogramminglanguage.net/c-bubble-sort-source-code.aspx
void aimoves_sort(AIMoves *moves)
{
        //qsort(moves->data, moves->len, sizeof (AIMove), aimoves_compare);
	bublesort(moves->data,moves->len);
 
}
 
//void aimoves_subtract(AIMoves *m1, const AIMoves *m2)
//{
//        int i, j;
//
//        for (i = 0; i < m1->len; i++)
//                for (j = 0; j < m2->len; j++)
//                        if (m1->data[i].x == m2->data[j].x &&
//                            m1->data[i].y == m2->data[j].y) {
//                                aimoves_remove_index_fast(m1, i--);
//                                break;
//                        }
//}
//
//const char *aiw_to_string(AIWEIGHT w)
//{
//        static char buffer[32];
//
//        switch (w) {
//        case AIW_WIN:
//                return "WIN";
//        case AIW_LOSE:
//                return "LOSS";
//        case AIW_NONE:
//                return "NONE";
//        default:
//                break;
//        }
//        if (w > 0)
//                g_snprintf(buffer, sizeof (buffer), "%010d (10^%.2f)", w,
//                           log10((double)w));
//        else if (w < 0)
//                g_snprintf(buffer, sizeof (buffer), "%010d (-10^%.2f)", w,
//                           log10((double)-w));
//        return buffer;
//}
 
/*
 *      Boards
 */
 
//Board board;
//AllocChain *board_root = NULL;
//int board_size=19, board_stride=21, move_no, move_last,
//    connect_k = 6, place_p = 2, start_q = 1;
//int opt_det_ai=1;
//gsize board_mem = 0;
 
//Player players[PIECES] = {
//        { PLAYER_HUMAN, SEARCH_NONE, 0 },
//        { PLAYER_HUMAN, SEARCH_NONE, 0 },
//        { PLAYER_HUMAN, SEARCH_NONE, 0 },
//};
//
//static GPtrArray *history = NULL;
 
static void board_init(Board *b)
{
//        memset((char*)b + sizeof (AllocChain), 0, sizeof (Board) -
//               sizeof (AllocChain));
int i,j;
for(i=0;i<board_stride;i++)
	b->data[i][0]=PIECE_ERROR;
for(i=0;i<board_stride;i++)
	b->data[i][board_stride-1]=PIECE_ERROR;
for(j=0;j<board_stride;j++)
	b->data[0][j]=PIECE_ERROR;
for(j=0;j<board_stride;j++)
	b->data[board_stride-1][j]=PIECE_ERROR;
for(i=1;i<board_stride-1;i++)
	for(j=1;j<board_stride-1;j++)
		b->data[i][j]=PIECE_NONE;
 
	//b->ac=(const AllocChain )0;	
	b->moves_left=0;	
	b->parent =0;	
	b->won    =0;	
	b->win_x1 =0;	
	b->win_y1 =0;	
	b->win_x2 =0;	
	b->win_y2 =0;	
	b->turn   =0;	
	b->move_x =0;	
	b->move_y =0;	
}
 
//AllocChain *board_alloc(AllocChain *ac)
//{
//        //Board *b = (Board*)ac;
//        //int i;
//
//        ///* Clear the old board */
//        //if (b) {
//        //        for (i = 1; i <= board_size; i++)
//        //                memset(b->data + board_stride * i + 1, 0,
//        //                       board_size * sizeof (PIECE));
//        //        board_init(b);
//        //        return (AllocChain*)b;
//        //}
//
//        ///* New boards are allocated with a 1-tile wide boundary of PIECE_ERROR
//        //   around the edges */
//        //b = (Board*)g_slice_alloc0(board_mem);
//        //memset(b->data, PIECE_ERROR, sizeof (PIECE) * board_stride);
//        //for (i = 1; i <= board_size; i++) {
//        //        b->data[i * board_stride] = PIECE_ERROR;
//        //        memset(b->data + board_stride * i + 1, 0,
//        //               board_size * sizeof (PIECE));
//        //        b->data[(i + 1) * board_stride - 1] = PIECE_ERROR;
//        //}
//        //memset(b->data + board_stride * (board_stride - 1), PIECE_ERROR,
//        //       sizeof (PIECE) * board_stride);
//        //board_init(&b);
//        //return (AllocChain*)b;
//}
 
void board_clean(Board *b)
{
        int y, x;
 
        for (y = 0; y < board_size; y++)
                for (x = 0; x < board_size; x++)
                        if (piece_at(b, x, y) >= PIECES)
                                place_piece_type(b, x, y, PIECE_NONE);
}
 
//void set_board_size(unsigned int size)
//{
//        //if (board_size == size)
//        //        return;
//        ////draw_marks(NULL, FALSE);
//        //achain_dealloc(&board_root, board_mem);
//        achain_dealloc(&aimoves_root, aimoves_mem);
//        //board_size = size;
//        //board_stride = size + 2;
//        //board_mem = sizeof (Board) + board_stride * board_stride *
//        //            sizeof (PIECE);
//        aimoves_mem = sizeof (AIMoves) + size * size * sizeof (AIMove);
//}
 
//Board *board_at(unsigned int move)
//{
//        if (move >= history->len)
//                return NULL;
//        return (Board*)g_ptr_array_index(history, move);
//}
 
int count_pieces(const Board *b, BCOORD x, BCOORD y, PIECE type, int dx, int dy,
                 PIECE *out)
{
        int i;
        PIECE p = PIECE_NONE;
 
        if (!dx && !dy)
                return piece_at(b, x, y) == type ? 1 : 0;
        for (i = 0; x >= 0 && x < board_size && y >= 0 && y < board_size; i++) {
                p = piece_at(b, x, y);
                if (p != type)
                        break;
                x += dx;
                y += dy;
        }
        if (out)
                *out = p;
        return i;
}
 
gboolean check_win_full(const Board *b, BCOORD x, BCOORD y,
                        BCOORD *x1, BCOORD *y1, BCOORD *x2, BCOORD *y2)
{
        int i, c1, c2, xs[] = {1, 1, 0, -1}, ys[] = {0, 1, 1, 1};
        PIECE type;
 
        type = piece_at(b, x, y);
        if (type != PIECE_BLACK && type != PIECE_WHITE)
                return FALSE;
        for (i = 0; i < 4; i++) {
                c1 = count_pieces(b, x, y, type, xs[i], ys[i], 0);
                c2 = count_pieces(b, x, y, type, -xs[i], -ys[i], 0);
                if (c1 + c2 > connect_k) {
                        if (x1)
                                *x1 = x + xs[i] * (c1 - 1);
                        if (y1)
                                *y1 = y + ys[i] * (c1 - 1);
                        if (x2)
                                *x2 = x - xs[i] * (c2 - 1);
                        if (y2)
                                *y2 = y - ys[i] * (c2 - 1);
                        return TRUE;
                }
        }
        return FALSE;
}
 
///* Convert a boord coordinate to alpha representation */
//const char *bcoord_to_alpha(BCOORD x)
//{
//        static char buf[2][32];
//        static int which;
//        int i, divisor = 26;
//
//        which = !which;
//        for (i = 0; i < sizeof (buf[which]) - 1; i++) {
//                div_t result;
//
//                result = div(x, divisor);
//                buf[which][i] = 'a' + result.rem * 26 / divisor;
//                if (i)
//                        buf[which][i]--;
//                x -= result.rem;
//                if (!x)
//                        break;
//                divisor *= 26;
//        }
//        buf[which][i + 1] = 0;
//        return g_strreverse(buf[which]);
//}
 
//// Get a string representation of board x/y coordinates (d7, h16, etc)
//const char *bcoords_to_string(BCOORD x, BCOORD y)
//{
//        static char buf[2][32];
//        static int which;
//
//        which = !which;
//        g_snprintf(buf[which], sizeof (buf[which]), "%s%d",
//                   bcoord_to_alpha(x), board_size - y);
//        return buf[which];
//}
//
/* Convert a string representation to coordinates */
void string_to_bcoords(const char *str, BCOORD *x, BCOORD *y)
{
        *x = 0;
        *y = 0;
        while (*str && *str >= 'a' && *str <= 'z') {
                *x *= 26;
                *x += *str - 'a';
                str++;
        }
        while (*str && *str >= '0' && *str <= '9') {
                *y *= 10;
                *y += *str - '0';
                str++;
        }
        if (*y)
                *y = board_size - *y;
}
 
const char *piece_to_string(PIECE piece)
{
        switch (piece) {
        case PIECE_WHITE:
                return "White";
        case PIECE_BLACK:
                return "Black";
        case PIECE_NONE:
                return "None";
        case PIECE_ERROR:
                return "Error";
        default:
                return "Mark";
        }
}
 
char piece_to_char(PIECE piece)
{
        switch (piece) {
        case PIECE_WHITE:
                return 'W';
        case PIECE_BLACK:
                return 'B';
        case PIECE_NONE:
                return '_';
        case PIECE_ERROR:
                return 'E';
        default:
                return 'M';
        }
}
 
//char *search_to_string(SEARCH s)
//{
//        switch (s) {
//        case SEARCH_NONE:
//                return "No search";
//        case SEARCH_DFS:
//                return "Depth first search";
//        case SEARCHES:
//                break;
//        }
//        return "Unknown";
//}
 
//void go_to_move(unsigned int move)
//{
//        Board board2;
//
//        if (!history)
//                history = g_ptr_array_sized_new(32);
//        if (move > history->len)
//                move = history->len;
//        if (move == history->len) {
//                //board2 = board_new();
//                if (&board)
//                        board_copy(&board, &board2);
//                g_ptr_array_add(history, &board2);
//                board2.parent = &board;
//        } else
//                //board2 = (Board*)g_ptr_array_index(history, move);
//        //&board = &board2;
//        move_no = move;
//        if (move_no > move_last)
//                move_last = move_no;
//}
 
//void clear_history(unsigned int from)
//{
//        int i;
//
//        if (!history)
//                return;
//        if (from >= history->len) {
//                g_warning("Attempted to clear future history");
//                return;
//        }
//        for (i = from; i < history->len; i++)
//                board_free(g_ptr_array_index(history, i));
//        g_ptr_array_remove_range(history, from, history->len - from);
//        move_last = from;
//}
/* Clear the board and history for a new game */
void new_game(Board *board,unsigned int size)
{
        //tree_view_clear(1);
        //clear_history(0);
        //set_board_size(size);
        //board = NULL;
        //go_to_move(0);
	//move_last=0;
	//move_no=0;
	board_init(board);
        board->moves_left = start_q;
        board->turn = PIECE_BLACK;
        //draw_board();
        //stop_ai();
        //setup_move();
}
void board_copy(const Board *from, Board *to){
int i,j;
for(i=0;i<board_stride;i++)
	for(j=0;j<board_stride;j++)
		to->data[i][j]=from->data[i][j];
 
	to->ac=	from->ac;
	to->moves_left=	from->moves_left;
	to->parent =	from->parent;
	to->won    =	from->won;
	to->win_x1 =	from->win_x1;
	to->win_y1 =	from->win_y1;
	to->win_x2 =	from->win_x2;
	to->win_y2 =	from->win_y2;
	to->turn   =	from->turn;
	to->move_x =	from->move_x;
	to->move_y =	from->move_y;
 
 
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2014 OpenCores.org, equivalent to ORSoC AB, all rights reserved. OpenCores®, registered trademark.