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

Subversion Repositories connect-6

[/] [connect-6/] [trunk/] [CONNECT6_CMDLINE/] [connect6_golden.cpp] - Rev 6

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

/*
    connect6.cpp
    June 9, 2011
    This file contains the game AI
    By Kevin Nam
 
*/
 
#include <time.h>
#include <stdlib.h>
 
#include "util.h"
#include "connect6.h"
 
// Subtract this many points for moves at the edges.
#define EDGEPENALTY 5
 
using namespace std;
 
/*  The cost function simply counts all of the consecutive stones of same colour in
    every direction from the spot for which the points is being calculated.
 
    Ex:
 
      .DDLL
      .DLDD
      DXDDD
      ...D.
 
    Above, X is the spot being calculated.
    The points would be 2 (above) + 2(topright) + 3(right) + 1 (left) = 8.
    It treats opponent's stones and own stones with equal weighting.
 
    Return 0 if the spot y,x is already taken, else return the calculated value
 
*/
static int calculatepoints_golden(char board[][19], int y, int x, char colour){
    int pts = 0, tempx = x, tempy = y, tcount = 0,bcount = 0;
    int lcount = 0,rcount = 0,trcount = 0,tlcount = 0,brcount = 0,blcount = 0;
    char tcolour = 0,bcolour = 0,lcolour = 0,rcolour = 0,tlcolour = 0,trcolour = 0,brcolour = 0,blcolour = 0;
 
    if (board[y][x] != 0)
        return 0;
 
    // scan column above
    if (y > 0){
        tempy = y-1;
        tempx = x;
        tcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != tcolour || board[tempy][tempx] == 0) break;
            tcount++;
            if (tempy == 0) break;
            tempy--;
        }
    }
    // scan column below
    if (y < 18){
        tempy = y+1;
        tempx = x;
        bcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != bcolour || board[tempy][tempx] == 0) break;
            bcount++;
            if (tempy == 18) break;
            tempy++;
        }
    }
    // scan row to left
    if (x > 0){
        tempy = y;
        tempx = x-1;
        lcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != lcolour || board[tempy][tempx] == 0) break;
            lcount++;
            if (tempx == 0) break;
            tempx--;
        }
    }
    // scan row to right
    if (x < 18){
        tempy = y;
        tempx = x+1;
        rcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != rcolour || board[tempy][tempx] == 0) break;
            rcount++;
            if (tempx == 18) break;
            tempx++;
        }
    }
    // scan diagonal topleft
    if (x > 0 && y > 0){
        tempy = y-1;
        tempx = x-1;
        tlcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != tlcolour || board[tempy][tempx] == 0) break;
            tlcount++;
            if (tempx == 0 || tempy == 0) break;
            tempx--;
            tempy--;
        }
    }
    // scan diagonal bottomright
    if (x < 18 && y < 18){
        tempy = y+1;
        tempx = x+1;
        brcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != brcolour || board[tempy][tempx] == 0) break;
            brcount++;
            if (tempx == 18 || tempy == 18) break;
            tempx++;
            tempy++;
        }
    }
    // scan diagonal topright
    if (x < 18 && y > 0){
        tempy = y-1;
        tempx = x+1;
        trcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != trcolour || board[tempy][tempx] == 0) break;
            trcount++;
            if (tempx == 18 || tempy == 0) break;
            tempx++;
            tempy--;
        }
    }
    // scan diagonal bottomleft
    if (y < 18 && x > 0){
        tempy = y+1;
        tempx = x-1;
        blcolour = board[tempy][tempx];
        while (1){
            if (board[tempy][tempx] != blcolour || board[tempy][tempx] == 0) break;
            blcount++;
            if (tempy == 18 || tempx == 0) break;
            tempy++;
            tempx--;
        }
    }
 
    /// Now calculate the points
    // Check if this is a winning move. Priority #1.
    if ((tcount >= 5 && tcolour == colour) ||
        (bcount >= 5 && bcolour == colour) ||
        (lcount >= 5 && lcolour == colour) ||
        (rcount >= 5 && rcolour == colour) ||
        (tlcount >= 5 && tlcolour == colour) ||
        (trcount >= 5 && trcolour == colour) ||
        (brcount >= 5 && brcolour == colour) ||
        (blcount >= 5 && blcolour == colour) ||
        (tcount + bcount >= 5 && tcolour == colour && bcolour == colour) ||
        (lcount + rcount >= 5 && lcolour == colour && rcolour == colour) ||
        (tlcount + brcount >= 5 && tlcolour == colour && brcolour == colour) ||
        (trcount + blcount >= 5 && trcolour == colour && blcolour == colour))
        return 1000;
 
    // Check if this move can stop opponent from winning. This move is priority #2.
    if ((tcount >= 4 && tcolour != colour) ||
        (bcount >= 4 && bcolour != colour) ||
        (lcount >= 4 && lcolour != colour) ||
        (rcount >= 4 && rcolour != colour) ||
        (tlcount >= 4 && tlcolour != colour) ||
        (trcount >= 4 && trcolour != colour) ||
        (brcount >= 4 && brcolour != colour) ||
        (blcount >= 4 && blcolour != colour) ||
        (tcount + bcount >= 4 && tcolour != colour && bcolour != colour) ||
        (lcount + rcount >= 4 && lcolour != colour && rcolour != colour) ||
        (tlcount + brcount >= 4 && tlcolour != colour && brcolour != colour) ||
        (trcount + blcount >= 4 && trcolour != colour && blcolour != colour))
        return 500;
 
    // Else sum up the counts, use this as the points.
    pts = tcount + bcount + lcount + rcount + tlcount + trcount + blcount + brcount + 1;
    // If at an edge, lower the points
    if (x == 0 || x == 18 || y == 0 || y == 18){
        if (pts >= EDGEPENALTY)
            pts -= EDGEPENALTY;
        else
            pts = 0;
    }
    return pts;
}
 
/*
    The AI Function that calls the cost function for every spot on the board.
    It returns the location with the highest points. In the event of a tie, randomly decide.
    Input the board and the colour being played.
    Puts the move (in ASCII chars) inside move[4]. This is from [1 ... 19]
    Puts the move (in integers) in moveY and moveX. This is from [0 ... 18]
*/
int connect6ai_golden(char board[][19], char colour, char move[4]){
    int x,y,highx = 0, highy = 0,currenthigh = 0, temp;
    srand(time(NULL));
    int highRandom = 1;//rand();
    // Sweep the entire board with the cost function
    for (x = 0; x <= 18; x++){
        for (y = 0; y <= 18; y++){
 
            temp = calculatepoints_golden(board,y,x, colour);
            if (temp > currenthigh){
                highx = x;
                highy = y;
                currenthigh = temp;
                highRandom = 1;//rand();
            }
            // If a tie happens, pseudo-randomly choose one between them
            if (temp == currenthigh && temp != 0){
                int tempRandom = 1;//rand();
                if (tempRandom > highRandom){
                    highx = x;
                    highy = y;
                    highRandom = tempRandom;
                }
            }
        }
    }
 
    // Modify the board based on current move.
    //board[highy][highx] = colour;
 
    // Increment by 1 because indexing starts at 1.
    highy++;
    highx++;
 
    /// Convert the int coordinates to corresponding ASCII chars
    if (highy >= 10){
        move[0] = '1';
        highy -= 10;
    } else {
        move[0] = '0';
    }
    if      (highy == 0) move[1] = '0';
    else if (highy == 1) move[1] = '1';
    else if (highy == 2) move[1] = '2';
    else if (highy == 3) move[1] = '3';
    else if (highy == 4) move[1] = '4';
    else if (highy == 5) move[1] = '5';
    else if (highy == 6) move[1] = '6';
    else if (highy == 7) move[1] = '7';
    else if (highy == 8) move[1] = '8';
    else if (highy == 9) move[1] = '9';
 
    // Do same for x.
    if (highx >= 10){
        move[2] = '1';
        highx -= 10;
    } else {
        move[2] = '0';
    }
    if      (highx == 0) move[3] = '0';
    else if (highx == 1) move[3] = '1';
    else if (highx == 2) move[3] = '2';
    else if (highx == 3) move[3] = '3';
    else if (highx == 4) move[3] = '4';
    else if (highx == 5) move[3] = '5';
    else if (highx == 6) move[3] = '6';
    else if (highx == 7) move[3] = '7';
    else if (highx == 8) move[3] = '8';
    else if (highx == 9) move[3] = '9';
 
    return 0;
}
 
 
 
 

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

powered by: WebSVN 2.1.0

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