Adding a blocker in a board to restrict cell access.

I have game of Abalone that I have created I am looking for ideas to insert a blocker on the board.

This blocker should be randomly inserted on the space that have + .

Note to visualise the board well I have inserted Z on the board the in the position F line 4

I O O O O O
H O O O O O O
G + + O O O + +
F + + Z + + + + +
E + + + + + + + + +
D + + + + + + + + 9
C + + @ @ @ + + 8
B @ @ @ @ @ @ 7
A @ @ @ @ @ 6
1 2 3 4 5

I would be great if you can give me ideas around this as I have whole running files but I cannot post the code here as they are long and are from different classes.

This blocker should be inserted in the dimension of the board which is octagon and each should be in the + cell and none of the players @ and 0 peices should move into this space since it has a blocker




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

bool board::validateMove(const char& m,const string& l,const int& n, const int& fd, const int& md, int& mtype, bool& scoreMove) const{

    if(!cell::validateLocation(l))//confirm existence of location
        return false;
    else{        
        cell* cp = cells.at(l);//initialize to leading cell
        const char marble = cp->getMarble();
        if(marble!=m)//trying to move a space or a marble that is not yours
            return false;
        for(int i=1;i<n;i++){
            cp=cp->getAdjacent(fd);
            if(cp==nullptr || marble!=cp->getMarble())//confirm availability and type of claimed resources
                return false;
        }
        if(fd==getAdjacentIndex(md)){//in-line move
            cp = cells.at(l);//initialize to leading cell
            mtype=0;//how many opponent marbles are in front of the leading marble i.e in the move direction
            for(int i=0;i<n;i++){
                cp=cp->getAdjacent(md);
                if(cp!=nullptr){//confirm availability of required resources
                    if(marble==cp->getMarble())//met own marble instead of space
                        return false;
                    if('+'!=cp->getMarble())//if it belongs to opponent
                        mtype++;//count opponent marbles
                    else
                        break;
                }
                else{
                    if(mtype>0)//opponent's marble will be pushed off the board
                        scoreMove=true;
                    else//if trying to push your own marble off the board
                        return false;
                    break;
                }
            }
            if(mtype>=n)//should only push fewer than n of the opponent's marbles
                return false;
        }
        else{//broad-side move
            mtype=-1;
            if(n<=1)//broad-side move must use at least 2 marbles
                return false;
            cp = cells.at(l);
            for(int i=0;i<n;i++){
                cell* dp=cp->getAdjacent(md);//destination pointer
                if(dp!=nullptr && '+' == dp->getMarble())//is there an empty space to move to?
                    cp=cp->getAdjacent(fd);
                else
                    return false;
            }
        }
        return true;
    }
}

bool board::executeMove(const char& m,const string& l,const int& n, const int& fd, const int& md){
    int moveType = 0;//default to in-line with no following marbles
    bool scoreMove = false;
    bool valid = validateMove(m,l,n,fd,md,moveType,scoreMove);
    if(valid){
        if(moveType==-1){//broad-side
            if(cells.find(l)==cells.end()) return false;
            cell* cp = cells.at(l);
            for(int i=0;i<n;i++){
                if(cp==nullptr) return false;
                cell* dp=cp->getAdjacent(md);//destination pointer
                if(dp==nullptr)
                    return false;
                dp->setMarble(cp->getMarble());
                cp->setMarble('+');
                cp=cp->getAdjacent(fd); 
            }
        }
        else{//in-line
            cell* cp = cells.at(l), *rearp=cp;
            const char marble = cp->getMarble();
            cell* frontp=cp->getAdjacent(md);
            for(int i=1;i<n;i++){
                rearp=rearp->getAdjacent(fd);
            }
            if(scoreMove){                
                frontp->setMarble(rearp->getMarble());
                rearp->setMarble('+');
                if(marble=='O')
                    boc++;
                if(marble=='@')
                    woc++;
            }
            else{
                cell* tipp = frontp;
                for(int i=0;i<moveType;i++){
                    tipp=tipp->getAdjacent(md);//looking for empty space
                }
                if(moveType!=0)//tipp is already equal to frontp
                    tipp->setMarble(frontp->getMarble());
                frontp->setMarble(rearp->getMarble());
                rearp->setMarble('+');
            }
        }
    }
    return valid;
}
Last edited on
don't overthink it.
if the blocker is seen by the players, just put a new symbol there, like * or something.
if the blocker is hidden until you try to move there, and then you 'discover' it, you will instead have to store the coordinates of it.
in either case, you check the symbol or the coordinates when a player moves and if they try to go into that square, you refuse to allow it.
basically a simple modification to validatemove() should do the trick.
Thanks, @jonnin. For the reply

I was looking into something like that but I was thinking of using pointers ideas that rather than having the blocker as a coordinates ad the method seems to be failing idea,

So to evaluate this in deep sense, I am navigating the board through pointers rather than index hence it is not so trivial to implement as suggested
a pointer is just another way to view the index. the logic would still work, you just compare addresses instead of offsets. This is why pointers and raw C arrays can share notation, is that the indexing is really just offsets from an address (the first entry, offset zero). Pointer comparison would work if the data were a non sequential memory block, like a student's graph or tree built with the classical pointer approach.
Last edited on
If the code is C then using raw pointers and char/numeric arrays is how things work. Especially if the array's size is determined at run time and memory has to be dynamically allocated. Manual memory management is necessary but also all too easy to mess up.

C++ has containers and smart pointers that remove the burden of memory management so you, the programmer can concentrate on getting code to work as expected.

std::vector is the usually considered closest C++ crossover for a C array, std::string for a C string (char array), and std::unique_ptr for a raw pointer.

https://cplusplus.com/reference/vector/vector/
https://cplusplus.com/reference/string/string/
https://cplusplus.com/reference/memory/unique_ptr/
Thank you, @jonnin, for the feedback on this and to @George P for the info and the relevant articles to refer to.
Topic archived. No new replies allowed.