
-----------------------------------
Nathan4102
Tue May 21, 2013 1:26 pm

Any way to shorten this?
-----------------------------------
I've got this code which checks nearby cells for mines, and increases the number by one for every mine it finds. The problem is, its REALLY long, and I feel like it could be shortened, I just don't know how. Is there any way to shorten this?

Cell_Array stuff

type Cells : %Record to store data for each cell
    record
        x1, y1 : int
        clicked, mine : boolean
        number : int
    end record

var cell_Array : array 1 .. 20, 1 .. 20 of Cells %Array of records, 1 per cell

Long code

procedure GenerateNumber
    var num : int := 0
    for i : 1 .. 20
        for ii : 1 .. 20
            if cell_Array (i, ii).mine = false then
                if i not= 20 then
                    if cell_Array (i + 1, ii).mine = true then
                        num := num + 1
                    end if
                end if

                if i not= 20 and ii not= 20 then
                    if cell_Array (i + 1, ii + 1).mine = true then
                        num := num + 1
                    end if
                end if

                if ii not= 20 then
                    if cell_Array (i, ii + 1).mine = true then
                        num := num + 1
                    end if
                end if

                if i not= 1 and ii not= 20 then
                    if cell_Array (i - 1, ii + 1).mine = true then
                        num := num + 1
                    end if
                end if

                if i not= 1 then
                    if cell_Array (i - 1, ii).mine = true then
                        num := num + 1
                    end if
                end if

                if i not= 1 and ii not= 1 then
                    if cell_Array (i - 1, ii - 1).mine = true then
                        num := num + 1
                    end if
                end if

                if ii not= 1 then
                    if cell_Array (i, ii - 1).mine = true then
                        num := num + 1
                    end if
                end if

                if i not= 20 and ii not= 1 then
                    if cell_Array (i + 1, ii - 1).mine = true then
                        num := num + 1
                    end if
                end if
            end if

            cell_Array (i, ii).number := num
            num := 0

        end for
    end for
end GenerateNumber

-----------------------------------
Dreadnought
Tue May 21, 2013 6:05 pm

Re: Any way to shorten this?
-----------------------------------
If I understand your code right then something like this might be easier.

[code]I'm assuming grid is NxN and has indices ranging from 1 to N.

for (i,j) in grid
    if grid(i,j) != mine
        for x in max(i -1, 1) to min(i + 1, N)
            for y in max(j - 1, 1) to min(i + 1, N)
                if grid(x,y) == mine
                    grid(i,j).value += 1
                end if
            end for
        end for
     end if
end for

Observe that min and max allow us to cover all the edge cases
[/code]

-----------------------------------
Raknarg
Wed May 22, 2013 10:14 am

RE:Any way to shorten this?
-----------------------------------

for x : 1 .. maxcolumns
    for y : 1 .. maxrows
        if grid (x, y) = not_a_mine then
            for i : x - 1 .. x + 1
                for j : y - 1 .. y + 1
                    if grid (i, j) = mine then
                        %add to number of mines count
                    end if
                end for
            end for
        end if
    end for
end for


Thought I might rewrite that a bit

-----------------------------------
Nathan4102
Wed May 22, 2013 2:29 pm

RE:Any way to shorten this?
-----------------------------------
Ahh, Thanks for rewriting that Raknarg. I wasn't too sure what Dread was saying. Thanks both of you, this should work perfectly.

-----------------------------------
Dreadnought
Wed May 22, 2013 5:52 pm

Re: Any way to shorten this?
-----------------------------------
I didn't really intend for it to work out of the box but anyway, it should be

for x : 1 .. maxcolumns 
    for y : 1 .. maxrows 
        if grid (x, y) = not_a_mine then 
            for i : max(x - 1, 1) .. min(x + 1, maxcolumns)
                for j : max(y - 1, 1) .. min(y + 1 , maxrows)
                    if grid (i, j) = mine then 
                        %add to number of mines count 
                    end if 
                end for 
            end for 
        end if 
    end for 
end for

Note that if you omit the max and min then you get unwanted behavior for all the edge cases.

-----------------------------------
Raknarg
Wed May 22, 2013 6:08 pm

RE:Any way to shorten this?
-----------------------------------
oh, good call. I usually just throw in some if statements, I never thought of that.

-----------------------------------
Nathan4102
Wed May 22, 2013 6:29 pm

RE:Any way to shorten this?
-----------------------------------
Just added into my code, works perfectly! Thanks!
