Thread: Need help w/2d array game function

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    17

    Need help w/2d array game function

    Hello,

    I am writing a Connect-4 computer game based on the classic "board game." It is written in C++ as a Console Mode program. For those that don't know, you have a 7x6 "board" filled with empty slots.

    000000
    000000
    000000
    000000
    000000
    000000
    000000


    It is a 2 player game where each player (let's use symbols 1 and 2 respectively) tries to connect 4 of their markers in a variety of ways. For example:

    EXAMPLE 1 EXAMPLE 2 EXAMPLE 3
    000000 000000 000000
    000000 020000 010020
    111100 002000 020020
    000000 000200 000020
    000000 000020 000020
    000000 000000 000000
    000000 000000 000000

    Get the picture? Pretty simple? My question is: what routine would I write to check if player 1 or 2 is the winner and how would I implement it? I used a "brute force" routine for Tic-Tac-Toe (only 3x3; just took awhile to code), but I don't want this to take quite so much work. Any suggestions?

    Thx for your help!,

    cpp4ever
    ------------------------------------------
    Normally I'd put something clever, but that isn't the point of being here now is it?

  2. #2
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753

    Yes

    I did the same thing for my tic tac toe game, and now i'm going to do connect 4 and battleship. you can make the win checking a lot easier with loops. Here is how I did it in tic tac toe:

    {
    int w;
    char d;
    for(int p=1;p<=2;p++)
    {
    if(p==2)
    {
    d='O';
    w=2;
    }
    for(int g=1;g<4;g++)
    {
    if(board[1][g]==d && board[2][g]==d && board[3][g]==d)
    {
    win=w;
    }
    }
    for(int t=1;t<4;t++)
    {
    if(board[t][1]==d && board[t][2]==d && board[t][3]==d)
    {
    win=w;
    }
    }
    if(board[1][1]==d && board[2][2]==d && board[3][3]==d)
    {
    win=w;
    }
    if(board[3][1]==d && board[2][2]==d && board[1][3]==d)
    {
    win=w;
    }
    }
    }

    Thats all i have to say.

  3. #3
    Unregistered Leeman_s's Avatar
    Join Date
    Oct 2001
    Posts
    753

    ok

    ok I thought of a way. Do this:

    for(int g=1;g<=7;g++)
    if(board[g][z]=='X' && board[g][(z-1)]=='X' &&
    board[g][(z-2)]=='X' && board[g][(z-3)]=='X'){
    win=1;
    }

    ok that would check for all horizontal wins. Do you get what im saying? Then you do the similar for vertical and... diagonal would be harder. This is assuming your array for the board is board. And you use g and z for the row and column. And um if you use it, say "and a special thanks to leeman_s". Hehe. I'm serious.

  4. #4
    Registered User
    Join Date
    Nov 2001
    Posts
    30
    ok, excuse me for being blunt...I will use the excuse that I am a bit intoxicated (which makes it hard to type) but what I see is crap...... so, the right answer, well no right answers, but a good solution: recursion

    Use a recursive fuction that checks up, down, diagonol (wow, I don't know how to spell), left, right... remind me in the morning and I'll write the code for you if you don't know how to. Good night ....yawn

  5. #5
    Registered User
    Join Date
    Sep 2001
    Posts
    412
    Why not just check to see if the last piece played won the game? You need to check much fewer cases then -- and the game can only be won after any turn if that piece won the game.

  6. #6
    Registered User
    Join Date
    Oct 2001
    Posts
    17

    Yes, if you have time post code

    Ender,

    I trust you are feeling well this morning? > Anyways, if you have time to write the code it would be much appreciated. I am compiling the responses right now to test all answers, so yours would be appreciated if/when you have the time.

    Thanks
    ------------------------------------------
    Normally I'd put something clever, but that isn't the point of being here now is it?

  7. #7
    Registered User
    Join Date
    Nov 2001
    Posts
    30
    after a few glasses of water my head has cleared up a bit.... ok 2 things

    yes, checking the last pieced played would be a given, BUT, and that was a big but, do you want ai? If you do, this is where I would have the ai "strategize"...look for block, look for an opening that gave them, etc

    now, the checking part...

    Not sure how you have your board set up...you say an array, but I would probably make it atleast a struct, class would be better.
    I think I'm going to write a separate slot class that has a tree style to it where each slot has pointers to its adjacent slots, then you can recursively check each one of those, passing a count each time...when you get a count of 4, return true, otherwise return false, something like that.....like this

    class Slot {
    public:

    Slot();
    bool getState() {return state;}
    bool checkAdjacent(int dir);

    private:

    bool state;
    Slot *left, *right, *up, *down, *duleft, *duright, *ddleft, *ddright;
    // dd = diagonally down, du = diagonally up
    }

    Slot::Slot() {

    state = false;
    left = right = up = down = duleft = duright = ddleft = ddright = NULL;
    }

    bool Slot::checkAdjacent(int dir) {

    switch( dir ) {
    case LEFT: if(left = NULL) return false;
    return left->getState();
    case RIGHT: if(right = NULL) return false;
    return right->getState();

    ... it just occured to me, that since I defind the directions below, I could just have an array of slot pointers for the adjacent slots, but I'm not rewriting all this, you can do that.

    ie. class Slot {
    ...
    ...
    private:
    Slot *adj[ADJ_POSITIONS]; // adjacent positions would = 8

    I'm going to assume a board class with atleast the following:
    (Oh yeah, defining the 8 possible directions, you'll need those...but I'm sure you have those already)
    const int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3, DULEFT = 4, DURIGHT = 5,
    DDLEFT = 6, DDRIGHT = 7,

    ROWS = 7, COLUMNS = 6;


    class Board {
    public:

    Board();
    bool checkDir(slot *s,int x,int y)
    bool checkWin(int x, int y);

    private:

    slot *board[COLUMNS][ROWS]; // This makes checking evaulation of an
    // (x,y) coord. instead of (y,x)...although
    // I don't think this is "standard order
    // when dealing with such 2 dimensional
    // arrays, but eh...
    bool checkWin(slot *s, int cout, int direction);
    }

    Board::Board() {
    int row, col;

    for(col=1; col<COLUMNS; col++)
    for(row=1; row<ROWS; row++) {
    board[col][row]->left = board[col-1][row];
    board[col][row]->right = board[col+1][row];
    board[col][row]->down = board[col][row-1];
    board[col][row]->up = board[col][row+1];
    board[col][row]->duleft = board[col-1][row+1];
    board[col][row]->duright = board[col+1][row+1];
    ... // Yeah, I got tired of copy, paste, edit
    }

    // The 2 border rows and 2 border columns must have their outside
    // slot pointers set to null, I'll let you deal with that, just 4 more for loops,
    // acutally only 2
    }

    bool Board::checkWin(int x, int y) {
    if(checkDir(LEFT, x, y) // I guess instead of x, y, you could pass board[x][y]
    // actually that would be better....did I mention I'm
    // writing this as I go?
    if(checkWin(board[x-1][y], 2, LEFT)
    return true;

    if(checkDir(RIGHT, x, y)
    if(checkWin(board[x+1][y], 2, RIGHT)

    .... I think you can figure out where this is going

    else return false;
    }
    bool Board::checkDir(int dir, int x, int y) {
    // If I had slots with adjacent slot pointers in an array I could get rid of this
    // switch statement as well as the one above...
    switch( dir ) {
    case LEFT: return board[x][y]->checkAdjacent(LEFT);

    ...
    }

    // See, you replace the 8 slot pointers, for adjacent slots, with an array and
    // replace the passing of x, y, with board[x][y] (we'll call it's replacement s)
    // and this would be simplified to: return s->checkAdjacent(adj_slot[dir]);
    }

    So that gives you pretty much everything you need....I began to confuse myself, constantly revising as I went. There is much optimization that can be done with this probably. There is also excessive wrapping going on...no, not the music style. I'm a wrap fiend...there I'm referring to the music style, but only in jest. Anyways, I'm gonna go drink some more water, take some pills and pray this headache goes away.

  8. #8
    Registered User
    Join Date
    Nov 2001
    Posts
    30
    Screwed up here

    >bool checkDir(slot *s,int x,int y)
    Meant to write either checkDir(int dir, slot *s) or checkDir(int dir, int x, int y), *s and x,y would be redundant. Actually it has to be slot *s now that I look at it. so nearly everwhere where I put int x, y and then use board[x][y] has to be a slot pointer since I later use the below function with a slot pointer...the x, y would be lost on the first pass

    >bool checkWin(slot *s, int cout, int direction);

    Sorry, forgot to write the helper function for the overloaded checkWin()
    This is kind of important...here goes

    bool checkWin(slot *s, int count, int direction) {

    if(count == 4) return true;

    if checkDir(direction, s)
    return checkWin(slot s->adjacent_slots[direction], count++, direction);

    return false;
    }

    there, that's the recursion that I was talking about. Now this will only run twice at max...maybe you could just put that in a for loop. Wow, I feel bad for insulting that guy last night. I'm producing crap too...I'd feel bad anyways, but ....oh right, back to the programming....I have no more to say about it. Hope this helps.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  2. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  3. Help with an Array
    By omalleys in forum C Programming
    Replies: 1
    Last Post: 07-01-2002, 08:31 AM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM