Passing Pointer as Parameter

Long story short, I'm doing a version of Langton's ant for a class. It's the first time I've had to really split up code (assignment requires it) so I'm passing a lot of data inbetween classes and functions. I need to pass info from a menu function to an ant class, and then eventually all that will funnel into the main function.

I have the menu set up to have pointer variables so that main can reference them easily. However I'm having trouble passing the pointers as parameters to the ant class. The errors keep coming up as "can't convert int to *int" and things like that, but I've tried many combo's of &, *&, *, ** and the error just keeps changing to some variant of the original.

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
#ifndef ANT_HPP
#define ANT_HPP


// ant class declaration

class Ant

{
	private:

	//keeps track of where the ant is
	int xRow;
	int yCol;

	//tracks ant orientation
	int orient;

	public:

	int antRow(int *row);
	int antCol(int *column);

};

#endif



/***************
Is passed pointer as parameter, validates integer for xRow and sets private variable
***************/
int Ant::antRow(int *row)
{
			
		xRow = getInt();
		while (xRow<1 || xRow>*row)
		{
			std::cout << "Value is off the board, please try again." << std::endl;
			xRow = getInt();
		}

		return xRow;

}





/**********
part of menu function *****/
Ant bug;
std::cout << "How many rows will your gameboard have? " << std::endl;
	*row = getInt();
	while (*row<1)
	{
	std::cout << "Value cannot be less than 1, please try again." << std::endl;
	*row = getInt();
	}
        std::cout << "You've chosen " << *row << " row(s)." << std::endl;


.

.

.

std::cout << "What row will your ant start in? (Please choose a number 1-" << *row << ")" << std::endl;

startRow = bug.antRow(&row);

std::cout << "The ant will start in row " << startRow << "." << std::endl;


You haven't provided a whole lot of information, but you do not need pointers. The Ant class should know its own position. Other things should refer to the current ant to know where the ant is.

What the ant does need to know is its terrain. That is, it should have access to the gameboard. Do this with a reference. Your main should look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
  int rows = ask_user( "How many rows will your gameboard have? ",    100, 10000 );
  int cols = ask_user( "How many columns will your gameboard have? ", 100, 10000 );
  Gameboard gameboard( rows, cols );
  
  int row = ask_user( "What row will your ant start at? ",    1, rows ) - 1;
  int col = ask_user( "What column will your ant start at? ", 1, cols ) - 1;
  Ant ant( gameboard, row, col );

  int steps = ask_user( "How many steps should the ant take? ", 1, std::numeric_limits<int>::max() );
  ...
}

Notice how I created a function to help ask the user for a value in a given range.

1
2
3
4
5
6
int ask_user( const std::string& prompt, int min, int max )
{
  ...
  // if something goes wrong, either fix the error [such as returning (max-min)/2+min]
  // or print a message and exit().
}

You can even fix your prompts to give a default value, such as:

 
  int rows = ask_user( "How many rows will your gameboard have (default:500)? ", 100, 500, 10000 );

You can make this part of the input work however you want.


Your Ant class looks fine as-is: just add a reference to the gameboard as a private or protected member, and design your constructor appropriately.


I do not know how you are supposed to report the results of the computation. If you have an easy way to display to an image or to a window that would be nice. You can even do a display loop for each step of the ant so that the user can watch the patterns emerge. (Though I suspect this is not likely part of your assignment.)

You can easily create a text file with the results as well. When the ant finishes, just dump the gameboard to a file, using any two highly contrasting characters, such as   and # . That way you (and your professor) can load it up in a plain-text (fixed-font) editor and see the highway.


After that it is just using a loop to tell the ant to make each successive step.

Unless your assignment forbids it, terminating at a wall is not very friendly. Your options are:
  • terminate (easy and boring)
  • wrap around the gameboard (most interesting, IMHO)
  • create a new rule to turn the ant away from the wall
  • expand the gameboard (hard)

Hope this helps.
Last edited on
You're right, I didn't actually end up needing pointers and was just making it more complicated for myself. Also we aren't allowed to terminate the program until the specified number of steps has been reached... so I think something i might do is have the program skip the step that would put it out of bounds to go to the next step. I'd love to wrap it around the board but it just seems really daunting.

Thank you!
I played with this on my own...

A 100 to 200 cell grid is sufficient for most designs, and you start getting the road around 10,000 steps off an empty (pure white or pure black) grid. You might want to run to 12,000 steps or so to see something nice.

Heh, here’s a Tcl/Tk script to play with it.
https://www.activestate.com/products/activetcl/

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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#! /usr/env wish

# Langton's Ant

# 2019 Michael Thomas Greer
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
#  https://www.boost.org/LICENSE_1_0.txt )

package require Tk

# -------------------------------------------------------------------------------------------------
# colors
# -------------------------------------------------------------------------------------------------
set white #FFF
set black #000
set grey  #DDD   ;# grid line
set red   #F00   ;# ant
set green #000   ;# user modified cell

set black_rgb [winfo rgb . $black]
set next_ok   false

# -------------------------------------------------------------------------------------------------
# dimensions
# -------------------------------------------------------------------------------------------------
#set grid_size  150
#set cell_size  4
set grid_size  100
set cell_size  6
set image_size [expr {1 + $cell_size * $grid_size}]

proc x0 x {expr {0 + $x * $::cell_size}}
proc x1 x {expr {1 + $x * $::cell_size}}
proc xD x {expr {($x + 1) * $::cell_size}}

# -------------------------------------------------------------------------------------------------
# image
# -------------------------------------------------------------------------------------------------
set image [image create photo -width $image_size -height $image_size]

proc set.pixel {x y color} {$::image put $color -to [x1 $x] [x1 $y] [xD $x] [xD $y]}
proc get.pixel {x y}       {$::image get [x1 $x] [x1 $y]}

proc toggle.pixel {x y} {
  switch [get.pixel $x $y] \
    $::black_rgb {set.pixel $x $y $::white; return left } \
    default      {set.pixel $x $y $::black; return right}
}

# -------------------------------------------------------------------------------------------------
# ant
# -------------------------------------------------------------------------------------------------
proc initialize.ant {} {
  set ::x     [expr {$::grid_size / 2}]
  set ::y     $::x
  set ::dir   up
  set ::steps 0
}

set ant_dimension [expr {$cell_size + 1}]
set ant [image create photo -width $ant_dimension -height $ant_dimension]
$ant put $red -to 0 0 $ant_dimension $ant_dimension

proc place.ant {} {place $::GUI(ant) -x [x0 $::x] -y [x0 $::y]}
proc incr.steps {{n 1}} {$::GUI(steps) config -text [incr ::steps $n]}

proc turn dir {
  switch $dir {
    left  {set ::dir [string map {up right right down down left left up} $::dir]}
    right {set ::dir [string map {up left left down down right right up} $::dir]}
  }
}

proc incr_mod {var dir} {
  upvar 1 $var x
  set x [expr {($x + $dir + $::grid_size) % $::grid_size}]
}

proc step {} {
  switch $::dir {
    up    {incr_mod ::y -1}
    down  {incr_mod ::y  1}
    left  {incr_mod ::x -1}
    right {incr_mod ::x  1}
  }
  place.ant
  incr.steps
}

proc next {{n 1}} {
  history.push
  turn [toggle.pixel $::x $::y]
  step
  if {$::next_ok} {after 10 next} \
  elseif {$n > 1} {tailcall next [incr n -1]}
}

proc back {{n 1}} {
  if {[llength $::history]} {
    history.pop
    toggle.pixel $::x $::y
    incr.steps -1
    if {$n > 1} {tailcall back [incr n -1]}
    place.ant
  }
  focus .
}

# -------------------------------------------------------------------------------------------------
# history
# -------------------------------------------------------------------------------------------------
proc history.push {} {
  set ::history [list [list $::x $::y $::dir] {*}$::history]
}

proc history.pop {} {
  set ::history [lassign $::history h]
  lassign $h ::x ::y ::dir
}

# -------------------------------------------------------------------------------------------------
# GUI
# -------------------------------------------------------------------------------------------------
proc stop {} {
  if {$::next_ok} start|pause
}

proc clear {} {
  stop
  after 100 {
    initialize.ant
    place.ant
    set ::steps -1
    incr.steps
    
    set ::history [list]
    $::image put $::white -to 0 0 $::image_size $::image_size
    for {set n 0} {$n < $::grid_size + 1} {incr n} {
      $::image put $::grey -to [x0 $n] 0 [x1 $n] $::image_size  ;# vertical grid lines"
      $::image put $::grey -to 0 [x0 $n] $::image_size [x1 $n]  ;# horizontal grid lines
    }
    
    focus .
  }
}

proc start|pause {} {
  set ::next_ok [expr {!$::next_ok}]
  if {$::next_ok} {
    $::GUI(start) config -text "Pause"
    next
  } {
    $::GUI(start) config -text "Start"
  }
  focus .
}

proc saveas {} {
  stop
  set filename [tk_getSaveFile \
    -title "Save Langston's Ant PNG" \
    -parent . \
    -confirmoverwrite yes \
    -defaultextension ".gif" \
    -filetypes {{{Portable Network Graphic Files} {.png}}} \
  ]
  if {$filename ne ""} {
    $::image write $filename -format png
  }
  focus .
}

proc get.stepsize {} {regsub -all -- {[^[:digit:]]} $::stepsize ""}

proc gostep {} {
  stop
  next [get.stepsize]
  focus .
}

proc goback {} {
  stop
  back [get.stepsize]
  focus .
}

proc toggle {x y} {
  if {$::next_ok} return
  set x [expr {$x / $::cell_size}]
  set y [expr {$y / $::cell_size}]
  toggle.pixel $x $y
}

# -------------------------------------------------------------------------------------------------
# Create GUI
# -------------------------------------------------------------------------------------------------
initialize.ant

set options {-bd 0 -highlightthickness 0}

pack                     [frame       .f                              {*}$options]           -side bottom -expand yes -fill x
pack  [set GUI(clear)    [ttk::button .f.clear    -text    "Clear"    -command clear]]       -side right
pack  [set GUI(back)     [ttk::button .f.back     -text    "Back"     -command goback]]      -side right -before $GUI(clear)
pack  [set GUI(stepsize) [ttk::entry  .f.stepsize -textvar stepsize   -width 13]]            -side right -before $GUI(back)
pack  [set GUI(step)     [ttk::button .f.gostep   -text    "Step"     -command gostep]]      -side right -before $GUI(stepsize)
pack  [set GUI(saveas)   [ttk::button .f.saveas   -text    "Save As"  -command saveas]]      -side right -before $GUI(step)
pack  [set GUI(start)    [ttk::button .f.start    -text    "Start"    -command start|pause]] -side right -before $GUI(saveas)
pack                     [label       .f.steps0   -text    " Steps: " {*}$options]           -side left
pack  [set GUI(steps)    [label       .f.steps    -text    "0"        {*}$options]]          -side left
pack  [set GUI(image)    [label       .image      -image   $image     {*}$options]]
place [set GUI(ant)      [label       .ant        -image   $ant       {*}$options]]          -x [x0 $x] -y [x0 $y]

set stepsize "Step Size: 100"

proc bind.button {btn cmd {focus {}}} {
  if {$focus ne ""} {set fcmd "focus $btn"} {set fcmd ""}
  bind $btn <Return> "$cmd; $fcmd; break"
  bind $btn <space>  "$cmd; $fcmd; break"
}

bind.button $GUI(clear)    clear
bind.button $GUI(back)     goback focus
bind.button $GUI(stepsize) gostep focus
bind.button $GUI(step)     gostep focus
bind.button $GUI(saveas)   saveas
bind.button $GUI(start)    start|pause

bind .              <Escape>      exit
bind .              <space>       start|pause
bind .              <Return>      start|pause
bind .              <Tab>         {if {[focus] eq "."} {focus $GUI(stepsize); break}}
bind .              <Shift-Tab>   {if {[focus] eq "."} {focus $GUI(start);    break}}
bind $GUI(image)    <ButtonPress> {toggle %x %y}
bind $GUI(ant)      <ButtonPress> {toggle [expr {$x * $cell_size}] [expr {$y * $cell_size}]; break}
bind $GUI(stepsize) <FocusIn>     {$GUI(stepsize) selection range 0 end}

wm title     . "Langton's Ant"
wm resizable . 0 0

clear

after 150 {focus -force .}

# TODO
# [ ] Add ability to load an initial state?
# [ ] Make stepsize affect play? 

Enjoy!
Topic archived. No new replies allowed.