Visual Basic Tic Tac Toe error - visual-studio-2010

hey everyone i'm trying to create ttt and it works but when i do a test run and i make a player win, the last character doesn't show. if it's supposed to be 3 X's or O's aligned, the computer will recognize the winning move and declare a winner but btnclicked.text s still = nothing. here's my code, i have no idea how to fix it and because of that, the if statements that would recognize a draw and produce an output an't be evaluated.
Private Sub btnMoveMade_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles _
btn00.Click, btn01.Click, btn02.Click, btn10.Click, btn11.Click, btn12.Click, btn20.Click,
btn21.Click, btn22.Click
Dim btnSquareClicked As Button = sender
Dim player1 As String = Me.txtName1.Text
Dim player2 As String = Me.txtname2.Text
Static chrTTT(2, 2) As Char
Static player As String = "X"
If btnSquareClicked.Text <> Nothing Then
MessageBox.Show("Invalid Move.")
Else
Dim index As String
index = btnSquareClicked.Tag
Dim x As Integer = Val(index.Chars(0))
Dim y As Integer = Val(index.Chars(1))
Call StoreMove(x, y, player, chrTTT)
If IsWinner(chrTTT) Then
player = player1
MessageBox.Show(player & "!, Congratulations, You Won!")
btnNewGame.Visible = True
ElseIf IsWinner2(chrTTT) Then
player = player2
MessageBox.Show(player & "!, Congratulations, You won!")
btnNewGame.Visible = True
ElseIf btn00.Text <> Nothing And btn01.Text <> Nothing And btn02.Text <> Nothing And btn10.Text <> Nothing And btn11.Text <> Nothing _
And btn12.Text <> Nothing And btn20.Text <> Nothing And btn21.Text <> Nothing _
And btn22.Text <> Nothing And IsWinner(chrTTT) = False And IsWinner2(chrTTT) = False Then
MessageBox.Show("Aww, it's a draw")
Else
If player = "X" Then
player = "O"
btnSquareClicked.Text = "X"
Else
player = "X"
btnSquareClicked.Text = "O"
End If
End If
End If
End Sub
Sub StoreMove(ByVal x As Integer, ByVal y As Integer, ByVal player As Char, ByRef TTT(,) As Char)
TTT(x, y) = player
End Sub
Function IsWinner(ByRef TTT(,) As Char) As Boolean
For row As Integer = 0 To 2
If TTT(row, 0) = TTT(row, 1) And TTT(row, 1) = TTT(row, 2) And TTT(row, 0) = "X" Then
Return True
End If
Next row
For col As Integer = 0 To 2
If TTT(0, col) = TTT(1, col) And TTT(1, col) = TTT(2, col) And TTT(0, col) = "X" Then
Return True
End If
Next col
If TTT(0, 0) = TTT(1, 1) And TTT(1, 1) = TTT(2, 2) And TTT(0, 0) = "X" Then
Return True
End If
If TTT(0, 2) = TTT(1, 1) And TTT(1, 1) = TTT(2, 0) And TTT(0, 2) = "X" Then
Return True
End If
Dim movesLeft As Boolean = False
For row As Integer = 0 To 2
For col As Integer = 0 To 2
If TTT(row, col) = Nothing Then
movesLeft = True
End If
Next col
Next row
If Not movesLeft Then
Return True
End If
Return False
End Function
Function IsWinner2(ByRef TTT(,) As Char) As Boolean
For row As Integer = 0 To 2
If TTT(row, 0) = TTT(row, 1) And TTT(row, 1) = TTT(row, 2) And TTT(row, 0) = "O" Then
Return True
End If
Next row
For col As Integer = 0 To 2
If TTT(0, col) = TTT(1, col) And TTT(1, col) = TTT(2, col) And TTT(0, col) = "O" Then
Return True
End If
Next col
If TTT(0, 0) = TTT(1, 1) And TTT(1, 1) = TTT(2, 2) And TTT(0, 0) = "O" Then
Return True
End If
If TTT(0, 2) = TTT(1, 1) And TTT(1, 1) = TTT(2, 0) And TTT(0, 2) = "O" Then
Return True
End If
Dim movesLeft As Boolean = False
For row As Integer = 0 To 2
For col As Integer = 0 To 2
If TTT(row, col) = Nothing Then
movesLeft = True
End If
Next col
Next row
If Not movesLeft Then
Return True
End If
Return False
End Function
End Class

Set the Button Text before you do anything else:
If btnSquareClicked.Text <> Nothing Then
MessageBox.Show("Invalid Move.")
Else
btnSquareClicked.Text = player
' ... rest of the code ...
End If

thanks a lot, i just tried it and it worked, but the the message box that is suppose to show when it's a draw till doesn't come up, instead it still tells me that one of the players won
ElseIf btn00.Text <> Nothing And btn01.Text <> Nothing And btn02.Text <> Nothing And btn10.Text <> Nothing And btn11.Text <> Nothing _
And btn12.Text <> Nothing And btn20.Text <> Nothing And btn21.Text <> Nothing _
And btn22.Text <> Nothing And IsWinner(chrTTT) = False And IsWinner2(chrTTT) = False Then
MessageBox.Show("Aww, it's a draw")
that's the section dedicated to checking for a draw.

Related

How do I check diagonals for my winning conditions in connect four?

I have coded my program so that it checks columns and rows for the win but I am not sure on how do it for the diagonals. Any help would be much appreciated!
%check if won with columns
for column = 1:7
counter = 0;
for row = 1:6
if(board(row,column) == player)
counter = counter + 1;
if(counter == 4)
fprintf('Du vinder! \n')
break
end
else
counter = 0;
end
end
end
%check if won by rows
for row = 1:6
counter = 0;
for column = 1:7
if(board(row, column) == player)
counter = counter + 1;
if(counter == 4)
fprintf('Du vinder! \n')
break
end
else counter = 0;
end
end
end
%check if won by diagonals

Ruby NoMethodError - Undefined method

The following is my code. I tried to only include the code where I think the problem may be.
Class Ship contains getStatus:
class Ship
def initialize(name, size, status, shipNumber, firedUpon)
#name = name
#size = size
#status = status
#shipNumber = shipNumber
#firedUpon = firedUpon
end
def setSize(nSize)
#size = nSize
end
def getSize
return #size
end
def setName(nName)
#name = nName
end
def getName()
return #name
end
def setStatus(nStatus)
#status = nStatus
end
def getStatus
return #status
end
def setFiredUpon(nFired)
#firedUpon = nFired
end
def getFiredUpon
return #firedUpon
end
def setShipNumber(nNum)
#shipNumber = nNum
end
def getShipNumber
return #shipNumber
end
def ==(rhs)
if (#name !=rhs.getName() || #size != rhs.getSize() || #status != rhs.getStatus() || #shipNumber != rhs.getShipNumber() || #firedUpon != rhs.getFiredUpon())
return false
end
return true
end
end
Class Board Calls upon getStatus and contains rangeIsOccupied:
load 'ship.rb'
class Board
def initialize()
#gameBoard = Array.new(100)
#Ships = Array.new(5)
#initialize all ships on board
r = 0
while(r < 100)
#gameBoard[r] = Ship.new('', -1, false, -1, false)
r = r + 1
end
#Ships[0] = Ship.new('Carrier', 5, true,0, false)
#Ships[1] = Ship.new('BattleShip', 4, true,1, false)
#Ships[2] = Ship.new('Cruiser', 3, true,2, false)
#Ships[3] = Ship.new('Submarine', 3, true,3, false)
#Ships[4] = Ship.new('Destroyer', 2, true,4, false)
end
def printBoard()
board_size = 10
alphabet = 'abcdefghijklmnopqrstuvwxyz'
puts 'x = hit ship' "\n" 'o = ship on board' "\n" 'm = empty space' "\n"
puts '---------------------------------------------------------' "\n"
puts ' |A| |B| |C| |D| |E| |F| |G| |H| |I| |J|'
s = 0
rownum = 0
printrow = true
while(s < 100)
if printrow
print rownum
print ' - '
print ' '
printrow = false
end
if #gameBoard[s].getShipNumber() != -1 && #gameBoard[s].getFiredUpon()
print 'x'
elsif(!#gameBoard[s].getStatus)
print 'm'
else
print 'o'
end
if s % 10 == 9
print "\n"
printrow = true
rownum = rownum + 1
else
print ' '
end
s = s + 1
end
end
def isValidDirection(x1, y1, x2, y2)
if x1 == x2 || y1 == y2
return true
end
return false
end
def rangeIsOccupied(x1, y1, x2, y2)
#if horizontal
if(y1 == y2)
while(x1 != x2)
if #gameBoard[(y1*10)+x1].
return true
end
if x1 > x2
x1 = x1 - 1
else
x1 = x1 + 1
end
end
if #gameBoard[(y1*10)+x1].getStatus
return true
end
else
while y1 != y2
if #gameBoard[(y1*10)+x1].getStatus
return true
end
if y1 > y2
y1 = y1 - 1
else
y1 = y1 + 1
end
end
if #gameBoard[(y1*10)+x1].getStatus
return true
end
end
return false
end
Class Game calls getBoard() and randomizeFleet, the start of the problem:
load 'player.rb'
class Game
def initialize()
#p1 = Player.new('', 1, true)
#p2 = Player.new('cpu', 2, false)
gamemode = 0
puts '---------------------------------------------------------'
print "Gamemodes:\n1. Player vs. CPU\n2. CPU vs. CPU\n"
puts '---------------------------------------------------------'
print "Please select a gamemode (1/2):\n: "
gamemode = gets.chomp
#p2.getBoard().randomizeFleet()
When I try to run my codeI get the error:
board:89:in rangeIsOccupied': undefined methodgetStatus' for nil:NilClass (NoMethodError)
I would like to overcome this issue.
if you are not sure that #gameBoard[(y1*10)+x1] will return a ship instance, then you can add another clause to your conditionals, like:
if #gameBoard[(y1*10)+x1] && #gameBoard[(y1*10)+x1].getStatus

Counting X's and O's in a string in Ruby

I'm not sure why my code is not working, I think my logic is right?
Have the function ExOh(str) take the str parameter being passed and return the string true if there is an equal number of x's and o's, otherwise return the string false. Only these two letters will be entered in the string, no punctuation or numbers. For example: if str is "xooxxxxooxo" then the output should return false because there are 6 x's and 5 o's.
ExOh(str)
i = 0
length = str.length
count_x = 0
count_o = 0
while i < length
if str[i] == "x"
count_x += 1
elsif str[i] == "o"
count_o += 1
end
i+=1
end
if (count_o == count_x)
true
elsif (count_o != count_x)
false
end
end
The problem with your code is the function declaration. Use def ExOh(str) at the start. It may help if you indented also.
def ExOh(str)
i = 0
length = str.length
count_x = 0
count_o = 0
while i < length
if str[i] == "x"
count_x += 1
elsif str[i] == "o"
count_o += 1
end
i+=1
end
if (count_o == count_x)
true
elsif (count_o != count_x)
false
end
end
By the way, a simpler solution using the standard library #count https://ruby-doc.org/core-2.2.0/String.html#method-i-count
def ExOh(str)
str.count('x') == str.count('o')
end

How to improve time complexity of this code piece?

I am having a hard time trying to down down the time. If this can be done in O(n^2) thatd be awesome.
def printDistance(file)
line = file.gets
if line == nil then return end
sz, sx, sy, ex, ey = line.split(/\s/)
#counter = 0
while line = file.gets do
if line[0...4] == "path"
else
x, y, ds, w = line.split(/\s/,4)
x = x.to_i
y = y.to_i
matrix= Array.new
later = Array.new
tmp = Array.new
processing = Array.new
if matrix[y].class != Array
matrix[y] = Array.new
end
if ds == "" #this cell has NO way to get to
matrix[y][x] = nil
else
matrix[y][x] = ds
end
end
end
for y in 0...matrix.length
processing[y] = Array.new
tmp[y] = Array.new
later[y] = Array.new
end
printing = Array.new
counter = 0
sy = sy.to_i
sx = sx.to_i
processing[sy][sx] = matrix[sy][sx]
matrix[sy][sx] = nil
puts "#{counter},(#{sx},#{sy})" #first one
counter += 1
loop do
print "#{counter},"
counter += 1
for y in 0...processing.length
for x in 0...processing[y].length
if processing[y][x].class != nil
tmp[y][x] = processing[y][x]
dirArr = tmp[y][x].to_s.split(//)
dirArr.each { |c|
if c == "u"
newY = y - 1
newX = x
elsif c == "d"
newY = y + 1
newX = x
elsif c == "l"
newY = y
newX = x - 1
else #c == r
newY = y
newX = x + 1
end
if matrix[newY][newX] != nil
tmpStr = "(#{newX},#{newY})"
printing.unshift(tmpStr)
later[newY][newX] = matrix[newY][newX]
matrix[newY][newX] = nil
end
}
end
end
end
printing.sort!
for i in 0...printing.length
print printing[i]
if i < printing.length - 1
print ","
end
end
printing = [] #resetting
puts
for i in 0...later.length
for j in 0...later[i].length
if later[i][j] != nil
processing[i][j] = later[i][j]
end
end
end
break if NotEmpty(matrix) == false
end
end
def NotEmpty (a)
for i in 0...a.length
for j in 0...a[i].length
if a[i][j] != nil
return true
end
end
end
return false
end
Basically this code reads in a file and places it in a 2-d array representing a maze, then based on maze's starting point it will perform a BFS to put all cells in order from closest to the start to the farthest, then print everything out
This code is now O(n^3) but I am trying to shrink it to O(n^2), is there anyway I can traverse a 2-d array and keeping track of the x and y values without using two forloops?
Any help is appreciated!! Thanks!

End keyword in ruby

I just try to solve problem #45 from project-euler using ruby. I know the approach. But I wrote the code, It doesn't run. I am new to ruby, I don't know why there has to be so many "end" keyword at the back(Or else the terminal will complain)
Here is the code:
class Test
def initialize()
end
def Triangle(n)
if 1 + 8*n < 0 then
return false
else
i1 = 0.5 * (-1 + Math.sqrt(1 + 8*n))
i2 = 0.5 * (-1 - Math.sqrt(1 + 8*n))
cut_i1 = i1.to_i
cut_i2 = i2.to_i
if (cut_i1 == i1) & (i1 > 0)
return true
else if (cut_i2 == i1) & (i2 > 0)
return true
else
return false
end
end
end
def Pentagonal(n)
delta = 1 + 24*n
if delta < 0 then
return false
else
r1 = (1.0/6) * (1 + Math.sqrt(delta))
r2 = (1.0/6) * (1 - Math.sqrt(delta))
cut_r1 = r1.to_i
cut_r2 = r2.to_i
if (cut_r1 == r1) & (r1 > 0)
return true
else if (cut_r2 == r1) & (r2 > 0)
return true
else
return false
end
end
end
def Hexagonal(n)
delta = 1 + 8*n
if delta < 0 then
return false
else
r1 = 0.25 * (1 + Math.sqrt(delta))
r2 = 0.25 * (1 - Math.sqrt(delta))
cut_r1 = r1.to_i
cut_r2 = r2.to_i
if (cut_r1 == r1) & (r1 > 0)
return true
else if (cut_r2 == r1) & (r2 > 0)
return true
else
return false
end
end
end
end
for i in (1...100)
o = Test.new
print o.Triangle(i)
end
end
end
end
What's happening. Every time I run the program from the terminal. It shows nothing....
It's because you are using else if instead of elsif. Compare:
if cond
# do something
elsif another_cond
# do something else
end
if cond
# do something
else
if another_cond
# do something else
end
end
With that in mind, your program does not do what you think it should. Fix the elsif's and see.

Resources