•

Check out our Community Blogs # DanielTan

Member Since 22 Jul 2013
Offline Last Active Apr 16 2014 04:09 PM     ### In Topic: D Programming Language.

14 April 2014 - 06:12 PM

I find D actually suits me, someone who loves Python well, in spite of all the curly braces and small library(compared to python). Too bad D does not really have a mature IDE of it's own yet (Codeblocks works well though)

### In Topic: Tkinter ball snake game

04 August 2013 - 06:36 PM

Right, now then, we would want to add some goals for our game, and I'll set it to be getting the highest points within a minute. Going along that, let's write some code for food that will give points, and to give a better challenge, let our ball grow.

```def create_food(self,ball):
if len(self.foodX) <self.time//1500 +1:
self.foodX.append(randint(50,250))
if len(self.foodY) <self.time//1500 +1:
self.foodY.append(randint(50,250))
for i in range(0,len(self.foodX)):
self.canvas.create_rectangle(self.foodX[i], self.foodY[i], self.foodX[i]+10, self.foodY[i]+10, fill="blue")
for i in range(0,len(self.foodX)):
if len(self.canvas.find_overlapping(self.foodX[i], self.foodY[i], self.foodX[i]+10, self.foodY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.foodX[i], self.foodY[i], self.foodX[i]+10, self.foodY[i]+10):
self.point+=100
self.size+=0.5
self.foodX.pop(i)
self.foodY.pop(i)
self.create_food(ball)
```

I have used the canvas.find_overlapping as a collision handler for the food (It will eat it if it touches it), but you can also change it to <find_enclosed> so that it will devour it only if the food is inside the circle.

The increased size can be a boon or bane for the player because next, we will also be creating traps to cut the game points and decrease the size.

```def create_trap(self,ball):
if len(self.trapX) <self.time//1500 +1:
self.trapX.append(randint(50,250))
if len(self.trapY) <self.time//1500 +1:
self.trapY.append(randint(50,250))
for i in range(0,len(self.trapX)):
self.canvas.create_rectangle(self.trapX[i], self.trapY[i], self.trapX[i]+10, self.trapY[i]+10, fill="red")
for i in range(0,len(self.trapX)):
if len(self.canvas.find_overlapping(self.trapX[i], self.trapY[i], self.trapX[i]+10, self.trapY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.trapX[i], self.trapY[i], self.trapX[i]+10, self.trapY[i]+10):
self.point-=50
self.size-=1
self.trapX.pop(i)
self.trapY.pop(i)
self.create_trap(ball)
```

The [self.time//1500] code means that squares will increase every 15 seconds (time is ticked by the millisecond).

The blue square is food while the red square is a trap.

Then we'll also be doing some powerups, that will appear for about a second and a half, every ten seconds.

```def create_powersize(self,ball):
if len(self.trapY) is 0 or self.time%1000 == 0 :
self.powerupX.append(randint(50,250))
self.powerupY.append(randint(50,250))
for i in range(0,len(self.powerupX)):
self.canvas.create_rectangle(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10, fill="yellow")
for i in range(0,len(self.powerupX)):
if len(self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10):
self.point+=150
self.size+=2
self.powerupX.pop(i)
self.powerupY.pop(i)
self.create_powersize(ball)

def create_powercoin(self,ball):
if len(self.trapY) is 0 or self.time%1000 == 0 :
self.powerupX.append(randint(50,250))
self.powerupY.append(randint(50,250))
for i in range(0,len(self.powerupX)):
self.canvas.create_rectangle(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10, fill="yellow")
for i in range(0,len(self.powerupX)):
if len(self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10):
self.point+=500
self.size-=0.5
self.powerupX.pop(i)
self.powerupY.pop(i)
self.create_powercoin(ball)
```

Now then, let's put everything into our <paint> code and voila! the basic game is completed.

```from tkinter import *
from random import*

'''New game to illustrate the use of tkinter to make a game that can handle collisions.
'''

class game:
def __init__(self):
self.root=Tk()
self.RUN=False

self.frame=Frame(bg="black")
self.frame.pack();

self.canvas=Canvas(self.frame, bg="black",width=300,height=300)
self.canvas.pack()

self.clock=Label(self.frame, bg="black", fg="white")
self.clock.pack()
self.points=Label(self.frame, bg="black", fg="white")
self.points.pack()
self.button=Button(self.frame, bg="black", fg="white", text="Click to start" ,command=self.start)
self.button.pack()

self.root.mainloop()

def start(self):
self.time=0
self.RUN=True

self.foodX=[]
self.foodY=[]

self.trapX=[]
self.trapY=[]

self.powerupX=[[],[]]
self.powerupY=[[],[]]

self.TEXT="Welcome to tkinter"
self.point=0

self.x=100
self.y=100
self.tempx=100
self.tempy=100
self.UP=False
self.DOWN=False
self.LEFT=False
self.RIGHT=False

self.size=3
self.canvas.bind("<ButtonPress-1>", self.onMClick)
self.run()

def run(self):
if self.RUN is True:
self.time+=1
self.clock['text']="TIME:" + str(self.time//100)
self.points['text']="Points gathered: " + str(self.point)
self.move(10*self.size,2)
self.paint()
self.root.after(10, self.run)

def end(self):
self.RUN=False
self.canvas.unbind("<ButtonPress-1>")

def create_food(self,ball):
if len(self.foodX) <self.time//1500 +1:
self.foodX.append(randint(50,250))
if len(self.foodY) <self.time//1500 +1:
self.foodY.append(randint(50,250))
for i in range(0,len(self.foodX)):
self.canvas.create_rectangle(self.foodX[i], self.foodY[i], self.foodX[i]+10, self.foodY[i]+10, fill="blue")
for i in range(0,len(self.foodX)):
if len(self.canvas.find_overlapping(self.foodX[i], self.foodY[i], self.foodX[i]+10, self.foodY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.foodX[i], self.foodY[i], self.foodX[i]+10, self.foodY[i]+10):
self.point+=100
self.size+=0.5
self.foodX.pop(i)
self.foodY.pop(i)
self.create_food(ball)

def create_trap(self,ball):
if len(self.trapX) <self.time//1500 +1:
self.trapX.append(randint(50,250))
if len(self.trapY) <self.time//1500 +1:
self.trapY.append(randint(50,250))
for i in range(0,len(self.trapX)):
self.canvas.create_rectangle(self.trapX[i], self.trapY[i], self.trapX[i]+10, self.trapY[i]+10, fill="red")
for i in range(0,len(self.trapX)):
if len(self.canvas.find_overlapping(self.trapX[i], self.trapY[i], self.trapX[i]+10, self.trapY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.trapX[i], self.trapY[i], self.trapX[i]+10, self.trapY[i]+10):
self.point-=50
self.size-=1
self.trapX.pop(i)
self.trapY.pop(i)
self.create_trap(ball)

def create_powersize(self,ball):
if len(self.trapY) is 0 or self.time%1000 == 0 :
self.powerupX.append(randint(50,250))
self.powerupY.append(randint(50,250))
for i in range(0,len(self.powerupX)):
self.canvas.create_rectangle(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10, fill="yellow")
for i in range(0,len(self.powerupX)):
if len(self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10):
self.point+=150
self.size+=2
self.powerupX.pop(i)
self.powerupY.pop(i)
self.create_powersize(ball)

def create_powercoin(self,ball):
if len(self.trapY) is 0 or self.time%1000 == 0 :
self.powerupX.append(randint(50,250))
self.powerupY.append(randint(50,250))
for i in range(0,len(self.powerupX)):
self.canvas.create_rectangle(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10, fill="yellow")
for i in range(0,len(self.powerupX)):
if len(self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10)) is not 1:
if ball in self.canvas.find_overlapping(self.powerupX[i], self.powerupY[i], self.powerupX[i]+10, self.powerupY[i]+10):
self.point+=500
self.size-=0.5
self.powerupX.pop(i)
self.powerupY.pop(i)
self.create_powercoin(ball)

def paint(self):
self.canvas.delete(ALL)
self.canvas.create_text(100,100, text=self.TEXT, fill="green")

if self.time//100<=60:
if 10*self.size >0:
self.TEXT="Welcome to tkinter"
ball=self.canvas.create_oval(self.x-10*self.size,self.y-10*self.size,self.x+10*self.size,self.y+10*self.size, fill="white")
self.create_food(ball)
self.create_trap(ball)
if self.time%1000 <=100 :
if randint(0,100)%2==0:
self.create_powersize(ball)
else:
self.create_powercoin(ball)
elif 10*self.size>150:
self.clock['text']="You lost"
self.end()
else:
self.clock['text']="You lost"
self.end()
else:
self.clock['text']="Time's up"
self.end()

def move(self, b,speed):
if self.UP==True and self.y-b>0:
self.y-=speed
elif self.UP==True and self.y-b<=0:
self.UP=False
self.DOWN=True
if self.DOWN==True and self.y+b<300:
self.y+=speed
elif self.DOWN==True and self.y+b>=300:
self.DOWN=False
self.UP=True
if self.LEFT==True and self.x-b>0:
self.x-=speed
elif self.LEFT==True and self.x-b<=0:
self.LEFT=False
self.RIGHT=True
if self.RIGHT==True and self.x+b<300:
self.x+=speed
elif self.RIGHT==True and self.x+b>=300:
self.RIGHT=False
self.LEFT=True

def onMClick(self,event):
self.tempx=event.x
self.tempy=event.y
if event.x> self.x and self.x is not self.tempx :
self.RIGHT=True
self.LEFT=False
elif event.x< self.x and self.x is not self.tempx :
self.LEFT=True
self.RIGHT=False
else:
self.x=self.tempx
self.RIGHT=False
self.LEFT=False
if event.y> self.y and self.y is not self.tempy :
self.DOWN=True
self.UP=False
elif event.y< self.y and self.y is not self.tempy :
self.UP=True
self.DOWN=False
else:
self.y=self.tempy
self.DOWN=False
self.UP=False

app=game()

```

The game will look something like this:

That's it for now! ### In Topic: 100 ways to print out "Hello CodeCall"

25 July 2013 - 03:28 AM

There's always still python #101 python

```from tkinter import *

class main:
def __init__(self):
self.mess=messagebox.showinfo("Test", "Hello Codecall")

main=main()
```

### In Topic: Tkinter Tic Tac Toe tutorial

23 July 2013 - 05:37 AM

There was some bug with the game AI in ticTT.py so I attached a new version, ticTT2.py, complete with documentation and complete AI(the original only had two aspects of game AI)

This is how the interface looks like: GUITTT1.gif   27.78KB   153 downloads

Now then, on to the single player programming, working from the main class we had(with double players).

First, we will start by initiating our single player function, self.start2()

```def start2(self):
#Starts single player
self.canvas.delete(ALL)
self.label['text']=('Tic Tac Toe Game')
self.canvas.bind("<ButtonPress-1>", self.dgplayer)
self._board()
self.TTT=[[0,0,0],[0,0,0],[0,0,0]]
self.i=0
self.j=False
#Trigger to check the validity of the move
self.trigger=False
```

Note that it's almost the same as the double player function, except that this binds self.dgplayer and an extra self.trigger boolean variable, which we will be using later in the code.

then, it's on to the single player code. This time, we'll just copy paste the double player function, and simply change the second player into our game AI player.

```def dgplayer(self,event):
for k in range(0,300,100):
for j in range(0,300,100):
if self.i%2==0:
if event.x in range(k,k+100) and event.y in range(j,j+100):
if self.canvas.find_enclosed(k,j,k+100,j+100)==():
X=(2*k+100)/2
Y=(2*j+100)/2
X1=int(k/100)
Y1=int(j/100)
self.canvas.create_oval( X+25, Y+25, X-25, Y-25, width=4, outline="black")
self.TTT[Y1][X1]+=1
self.i+=1
self.check()
self.trigger=False
else:
#check for wins/losts/draws first
#before allowing the computer to make its turn
self.check()
#Game AI code
self.AIcheck()
#refresh validity of move
self.trigger=False
```

Note that we should check if the game has ended before we let the AI player play.

Now then, comes the tricky part of designing an AI player.

Keep a few things in mind when coding an AI player:

1) Keep your code concise and precise as the AI is going to play every game loop。

2) Reuse your code if possible. Identify parts that keep repeating and write a function for it.

3) If possible, list out all the conditions that the player will meet.

4) There are three aspects of the game AI:Offense, Defense and Neutral.

Right, before I started coding, I played tic tac toe for some time and noted down what I did and what I thought at which conditions, which was basically doing (3) from above.

In this game:

1) the player starts first. If he chooses the center, the second player is going to have a tough time. If not, then the second player might just get the center.

2) I might not know what to do on the second move.

3) By the second and third move, I will start to attack, or block the other guy's attack.

4) I need to check the whole board for solutions.

5) Repeated draws circles or crosses.

From this, I gather that:

1)The AI needs to try to get the center.

2) There is a need for a random move function.

3) I need a function to loop through every row, column and diagonal to attack or defend.

4) I might need a function to draw circles and crosses.

And with that in mind, let's start writing code with (4) from the latter.

The circle drawing has been taken care of (in the self.dgplayer function)so we'll have to write code for the cross.

```def cross(self, k, j):
# k is the x coords
# j is the y coords
X=(200*k+100)/2
Y=(200*j+100)/2
X1=int(k)
Y1=int(j)
self.canvas. create_line( X+20, Y+20, X-20, Y-20, width=4, fill="black")
self.canvas. create_line( X-20, Y+20, X+20, Y-20, width=4, fill="black")
self.TTT[Y1][X1]+=9
self.check()
self.i+=1
self.trigger=True
```

Now then, we'll move on to the randmove function, which is (2)

```def randmove(self):
# In case there's nothing for the computer to do
while True:
k=(randint(0,2))
j=(randint(0,2))
if self.TTT[j][k]==0:
self.cross(k,j)
break
else:
k=(randint(0,2))*100
j=(randint(0,2))*100
```

Our matrix, self.TTT has only, 0,1,2, elements.

Then it's time for the juiciest part, the AIcheck function, which loops through every part of the matrix in search of a loophole.

Since the AI should have a desire to win, we should put OFFENSE code at the top (first to loop through), then DEFENSE, then finally NEUTRAL (when everything is exhausted)

Using self.trigger to signal that a move has been made eliminates the need for the error-prone elif statement ( since the code might jump here and there )

Again, we should recycle code that has already been written to save time and energy.

We'll recycle the check function to check for two circles or crosses in a row, then write the corresponding code to check for an empty space and draw a cross

Here's the code in it's full glory.

```def AIcheck(self):
#Offense should come before defense so that the AI will try to win if possible
#This is built on the self.check function
self.ttt=[[row[i] for row in self.TTT] for i in range(3)]
#OFFENSE
#this is the vertical checklist
for h in range(0,3):
k=0
j=0
if sum(self.TTT[h])==18:
while k <3:
if k==h:
while j <3:
if self.trigger==False:
if self.TTT[k][j]==0:
self.cross(j,k)
break
j+=1
k+=1
#this is the horizontal checklist
for h in range(0,3):
k=0
j=0
if sum(self.ttt[h])==18:
while k <3:
if k==h:
while j <3:
if self.trigger==False:
if self.ttt[k][j]==0:
self.cross(k,j)
break
j+=1
k+=1
#this is the diagonal checklist
if self.TTT==9:
if self.TTT==9:
if self.trigger==False:
if self.TTT==0:
self.cross(2,2)
if self.TTT==9:
if self.trigger==False:
if self.TTT==0:
self.cross(0,2)
if self.TTT==9:
if self.trigger==False:
if self.TTT==0:
self.cross(2,0)
if self.TTT==9:
if self.trigger==False:
if self.TTT==0:
self.cross(0,0)
#DEFENSE
#this is the horizontal checklist
for h in range(0,3):
k=0
j=0
if sum(self.TTT[h])==2:
while k <3:
if k==h:
while j <3:
if self.trigger==False:
if self.TTT[k][j]==0:
self.cross(j,k)
break
j+=1
k+=1
#this is the vertical checklist
for h in range(0,3):
k=0
j=0
if sum(self.ttt[h])==2:
while k <3:
if k==h:
while j <3:
if self.trigger==False:
if self.ttt[k][j]==0:
self.cross(k,j)
break
j+=1
k+=1
#this is the diagonal checklist
if self.TTT==1:
if self.TTT==1:
if self.trigger==False:
if self.TTT==0:
self.cross(2,2)
if self.TTT==1:
if self.trigger==False:
if self.TTT==0:
self.cross(0,2)
if self.TTT==1:
if self.trigger==False:
if self.TTT==0:
self.cross(2,0)
if self.TTT==1:
if self.trigger==False:
if self.TTT==0:
self.cross(0,0)
#NEUTRAL
if self.TTT==0:
if self.trigger==False:
self.cross(1,1)
self.trigger=True
else:
if self.trigger==False:
self.randmove()
```

I used while loops since the break statement is damn useful when I want to stop the loop after the move has been made.

Since we used a function to draw the cross, the code remains clean and easily understood.

I did not use a for loop for the diagonal checking since there are just 4 cases and it isn't worth the effort to design a for loop for this when we could have just copy pasted, and also since it's easy to maintain.

And we're done! Just put everything in, and you've a functional AI player!

Also, you can change the "personality" of your AI by changing the order of the OFFENSE, DEFENSE, NEUTRAL code. Try it out! LOL

I'm welcome to comments and bug explorers. Happy coding(and playing)!

This is a screenshot of an endgame:

### In Topic: Java:Tutorial - Tic-Tac-Toe

22 July 2013 - 04:29 AM

You also could have use a 2d array to store int values to mean cross and circles, then do summation to see if they add up to the winning scores

i.e. cross =>1, circle =>9, cross win=>3, circle win=>27

instead of using boolean calculation because they are three states: null, circle, cross,since you're already using an array to set up the buttons.
I tried it in python and it works fine. Also it keeps the code clean because you don't have to manually check every row/column.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download 