what's up guys
in this video i'm going to show you how
to program connect 4 in python
by the end of these videos you'll build
something that looks like this
it's a simple
two-player connect 4 game with graphics
i think this is a really good exercise
for your beginner to intermediate level
python programmers who want to build
their skills
i'll just finish up a game real quick
just so you can see how
this fully works
as you can see i have the diagonal and
it says player one wins cool we're gonna
do something a little bit simpler and
then build up to that graphic based
connect four game
it's a command line connect four game
where you actually manually type in
numbers to drop your pieces so you see
the one there
the two etcetera all right so let's
start building that
just quickly i want to mention that i'll
be programming in python 3 and then
using sublime text 2 as my editor i
posted a link to a video on how to set
up these things in the description
so one of the first questions i asked
myself when i was writing this game is
what is the best way to represent the
board
so if i drag on a connect 4 board real
quick you can see that it is 6 rows by 7
columns and to me this looks like the
perfect structure to represent as a
matrix in python so that's what we'll do
so we'll define a function called create
board
and that's not going to accept any
inputs
then we're going to make a
a matrix of all zeros with the
dimensions six by seven and to help us
do this we're going to import a package
called numpy
and if you haven't already installed
this you can open up a terminal window
and just type in pip install numpy
and as you can see i already have it
so we're going to use this as follows
we're going to say board equals
numpy dot zeros and that's going to make
a matrix of all zeros which is good for
our initial state and then the
dimensions six rows by seven columns
cool and then we just need to return
that board
and we can test to make sure that worked
by doing the following create board
and then
print
board and as you can see if i run oh no
what happened as you can see if i run
that
um we we do in fact have this six by
seven matrix of all zeros so that looks
good we can begin writing the main game
loop now
so we're going to write a loop that says
while not
game over
and so
our loop is going to be running as long
as
this game over variable is false
and the only way it becomes true is if
someone has a four in a row so we need
to initialize the game over to be false
to begin with
equals false and the only way that's
going to switch to true is if someone
got a four in a row
so now we're going to need to we're also
going to want to real quick
make our board initialize before we
start the game
just so we have something to put pieces
into
so we have our board we have our game
over variable and now we're going to
want to be able to ask
for player 1 input
and then we're also going to want to
eventually be able to ask
ask
for player 2 input
so this kind of leads us to the problem
of oh how do we differentiate between
whether it's player 1 or player 2's turn
so we're always going to define another
variable up here called turn that's just
going to initialize to 0. so what we're
going to say is
if turn
equals equals zero
then we're going to want to ask for
player one input
all right so in python there's a
function a built-in function called
input as you can see it highlights blue
for me
so
we're gonna say
selection equals
input and then
we're gonna say player one
make your selection so this is what the
player one is gonna see and then the way
we're going to initialize this game is
we're going to just say they can type in
between 0 and 6. so
this is what the
player 1 should see so if i build this
you see we run into this error
so this is because um sublime text
doesn't accept this input
function
so my work around for this was i
installed a package in sublime called
sublime repl i'll put a link in the
description on how to install this
and i can run
the input function through that so now
you can see player one make your
selection three
and it doesn't do anything with that
input right now but you can see that
it's asking me that and i can type in
hit enter
all right cool so we also just want to
make sure that it saves our selection
properly so we're going to print
selection
and i also just want to see you know if
i type in a number does it actually give
me the number
or does it give me a string that
represents the number so i'm going to
also print in type of selection i just
want to see what we're getting so i'm
going to run that again and as you can
see error again but we're going to go to
slime rpl and the link is in the
description as i just said run current
files so
two
and as you can see it gets two but it
says it's a string so we're going to
want to make sure that it's actually a
integer
so we can just surround this with int
input one and this should work so let's
see
run that again
and you can also run this through the
command line so if you run this in your
terminal go to the the directory that
the file is in and type in python and
then file name it will also run just as
i'm running it in this sublime repl
player one make your selection three
cool and now you see it says three and
it says the class of that is an int so
that looks good to me
so
now you can save some sort of selection
from the user and you can also
edit this so that it
requires you to make a specific
num type in a specific number but we'll
just leave it as like we'll imagine our
players are following the directions
right now
all right cool we have that and then
we're also going to want to be able to
ask for player 2's input so that's going
to happen else otherwise so if the turn
is not equal to zero
um
then we want to ask for player two input
so selection equals
and we'll just copy this from above
and we'll just have to change this to
say player two make your selection
all right
cool
and now at the end of the turn no matter
whose turn it is we're gonna want to
increase
um
our turn by one so turn plus e or plus
equals one so i'll make it increment it
by one and then we're also what we're
going to also want to do is
we're going to just make this odd even
so
we're going to use mod division so it's
going to be turn mod to turn equals
turn
mod
2 and this is just basically making it
go uh take the remainder of whatever our
turn is divided by 2.
so this is just going to alternate it
between 0 and 1. so it will alternate
between player 1's turn and player 2's
turn so
let's just see if this works properly so
we're going to run this
build python current file
player one make your selection two
player two make your selection four
player one make your selection two oh
that looks good it's alternating between
our player one and our player two
cool
okay and now we're gonna wanna start
building our actual functionality we're
gonna wanna be able to make this
selection right here actually drop a
piece into our board
so i'm going to find another function up
here called
definition drop
piece
and we might define a couple functions
so maybe have a drop piece and then
we'll just do pass for now and maybe
we'll also have like
is valid location
so that will check whatever number that
the
player typed in we'll check to see if
that's a valid location
we'll also define a function called get
next
open row
and how all these functions are going to
work together is as follows so it all
begins with the player making a
selection the 0 to 6 here represents the
column that they want to drop their
piece in so maybe a more appropriate
title for this would be
col representing column
col
next we're going to take this column and
the current board we have
and pass it into this is valid location
function so board column
and to visualize how we can check to see
if the column they selected is a valid
location
we will
print out the board real quick
so as you can see
imagine this is the
zeroth row is the first row second row
all the way up to the fifth row here and
then this is the zeroth column first
column second column etc we're starting
at zero as our first index
so if we wanted to check if the column
that the user selected let's just assume
that the user always types in a valid
number zero to six if we wanted to check
to see if it's valid all we need to do
is make sure that this top row
for that specific column is not been
filled
so
let's imagine that we're putting ones in
for player one going and two's in for
player two going so if this top row
is still zero for the specific column we
selected then we know that it's okay for
us to drop a piece in that row
or in that column it hasn't been filled
all the way to the top
so to do that so this is the fifth row
so all i'm going to do is just check to
see whether or not
the
position at the fifth row and let's say
you know whatever column we select is
zero and if it is that means the column
is still free if it's not then
that's not a valid location we'll have
to have the user try something else
so to do that let's just do board
so we're going to return
board
and then the
the row is 5
and the column is whatever the user
selected so here
so
and we're going to make sure that's
equal equals zero so if that's true then
we're good to
let them drop the piece there
if that's not true then that means the
column has been filled up all the way
and one thing i'll note that will
probably change in a future video is
that it's kind of getting messy my code
a little bit with just throwing these
random numbers here all the way all over
the place and programming these are
called magic numbers you kind of don't
know where they come from so i'll clean
those up in
some of the future videos in this series
so return board five column equals
equals zero and that is just checking to
make sure that that column has an empty
slot okay so now that we've gotten the
valid location let's get the next open
row in that column
so if we think back to our board
that's just checking to see when we drop
it in let's say
the zeroth column here on the the left
checking to see which
row of these if the piece will fall on
so to do this we're going to write a
quick little loop
so we're going to do
for
and we're gonna also have to pass in
the board and the column into this one
so the loop we're gonna write here is
for r and range
and i'm actually going to start
getting rid of some of these magic
numbers so i'm going to initialize
a
global variable called row count
and often globals are capitalized just
to show that or
static variables that don't change or
capitalize just to show that they're a
non-changing variable so the number of
rows we have is six and the number of
columns we have
is seven
so i'm going to do for r so for row in
range so the number of rows we have so
row count
we're going to check the board position
we're going to see
if board
r
position or so the column
equals equals zero
then we want to return that row so
basically if the row is equal to zero so
imagine we're filling this whole board
up with ones and twos
if the slot is still zero that means
it's empty still so we're going to
return the first instance that it's
empty so
this
r is going to count from zero to uh
row count minus one
and we're going to return that first
case where it equals zero
okay so now we've got the next open row
and then finally what we're going to
want to do is drop the piece so this is
going to take in the board
the row
and the column and then we'll also add
something we'll just call it
the piece so whether it's player one or
two going so
all this is going to do is go
board
row
column
equals equals the piece
so we're going to make it fill in
the board with whatever piece that the
player just dropped so let's put this
all together in our loop so first
we got the column and now we're going to
check
if is valid location of the board
in the column
and then we can start getting the next
empty row so row equals get next open
row
and that takes in the board and column
as well so
get next input and row
board
column
and then we're going to finally drop
piece
and we're gonna take in the board
the row the column and then for player
one the piece is just the one
and we're gonna copy this in
to player two as well because player one
and player two the functionality
of what they're doing is the same but
we'll just have to change the piece here
to two so
now and then finally probably after the
player goes we'll probably want to
print out the board so we'll print the
board here
and let's see what happens now so
tools build
oh shoot sorry supply more ipl python
run current file so player one selection
we're gonna drop our piece right in the
middle so that's zero one two three this
is the third column so three
uh what happened why did it not fill in
let's figure out what exactly went wrong
there so
should have updated the board but for
some reason it did not
um so let's see
okay i see what i did wrong here so
i accidentally put in
two equal sign here and what we're
really trying to do is an assignment
we're not trying to set see if the
boardrow column position is equal to
that so i didn't assign it so now it
should work so
we'll rerun this so tools supply maripl
python run current file player one make
your selection
we'll say go to the middle three
player two make your selection we'll do
three as well
player one make your selection and as
you can see one issue we're having right
now is that the pieces are
starting at the top and going downwards
and so the reason for this is
our convention was to say that this was
the zero zero index
but
in the actual numpy
they represent this right here as the
zero zero index
so i'm just going to add an additional
function real quick called
print board
and all that's going to do
is change the orientation
so that what we're seeing is actually
the
they flipped over the way we're
expecting to see a connect 4 board kind
of be building
from bottom up
so print board and we just need to pass
in the board and all we're going to do
is
there's a command
in dumpy
so the command is
let me just remember it it is
np.flip
i'm going to do
board and then you have to flip it over
you have to specify the axis so the 0 is
the axis we're going to flip the board
over the
x-axis
so that should get it upside the right
side up again so instead of doing
a print board here we're going to now
call our new print function so print
board
and then board
and we can also do that
down here if we want to
print
it doesn't matter i guess to start but
print board whatever
okay now let's run it again
tools it's primary pl python run current
file
player will make your selection three
three
three and as you can see now it's
building up from with ones and twos
just how we expect
the one problem with this is that if i
actually won this game so as you can see
i just went with player one down the
bottom
the game doesn't let me know at all that
i won so we need to implement that
functionality so we're going to define a
function called
winning
move
and we're going to have that taking the
board and then the last piece that was
dropped
so winning move there's a bunch of
different ways to implement this
and
the way we're going to do
is not the most efficient method but
it's probably the easiest to describe in
a video so that's kind of why i'm
selecting it but we're going to manually
check all the different
possible places you could win in connect
four so all the horizontals all the
verticals and all the diagonals
and check to see
if there is a winning combination on the
board
and because we're doing this after every
turn we're going to pick up the first
instance of that winning combination so
we'll know who won
probably the more practical way would be
to just check around the spaces where
the last piece was dropped but that code
got a little bit messier when i was
doing it before so i'm going to just do
it this way so we're going to first
check
all the horizontal
locations
and to do that we'll have a loop that
iterates over the columns so for c in
ca range
column count and so we defined a column
count up here above and that's seven
and one thing uh i think would be a cool
challenge for you guys to try that i
don't think my game is going to be able
to do at this point in time is a very
well designed like connect four game you
would be able to change these numbers so
like i could change it to say like 12 or
something
and this to like eight
and the game would still be able to work
you still have like a connect four game
but just a bigger board and so that's a
kind of a cool
way to make sure like you've designed
things
in a smart way where you don't have just
these random like magic numbers popping
up all over the place and i'm actually
going to change this real quick to row
count
and
column count just because i'm going to
try to eliminate the magic numbers where
i can and we'll clean this up to
uh row count
minus one so this is the last row the
left index of the last row okay getting
back to winning move so
we want to check horizontal locations
for the win so we're going to first loop
over all the
columns and then we're also going to
have a loop over all of the
rows
and what this loop is going to be over
is not
every single position but over all the
possible starting positions for a
horizontal wind
so if we think about our board a
horizontal wind can start
this spot this spot this spot and this
spot it can't start here because you
can't go
four over from this uh location so
this is our last column the third column
in terms of indices and then
upwards we can go all the way to the top
vertically because it can so
this half sorry you can't really see but
we're making a box around that half is
where our starting locations can be for
this first
um
this first check so we're iterating over
the columns so it can only be
the number of columns and then we have
to subtract three because three of those
columns
couldn't actually work
so we're subtracting three off of that
one and then all the rows could work so
that's totally fine so now we're going
to check
all the
four in a row location so
this is going to look like something
like this so
if
board
row
column so this is just indexing the
matrix
equals equals piece
and
board
row
c plus one so this is
taking the next one to the right so
we're checking horizontally so we're
only changing the columns equals equals
piece
and board
our c plus two
equals equals piece
and then finally and board this is the
fourth
piece in a row board
c plus three equals equals
peace
then we're going to return true
so we want to return true the first time
this happens we're not going to return
this expression because that would
return that would break out of this loop
before we wanted it to
okay and so what
we write again this is not the mo the
best way probably to write it you know
we have these magic numbers popping up
but it's just a very simple way to check
for all those horizontal locations right
so let's do the same thing with
vertical locations
locations for when
and actually before i do that let's just
uh check to see if we can get some
functionality
on this so if validation we're gonna
also write a
if statement that says if
winning
move
and
so we're going to say
board and then the piece is one
so if it's winning move we're gonna just
print out
uh player
one
wins
congrats
yay
okay let's just see if that works with
the horizontal real quick and then we're
also going to want to set this game over
variable
uh to true because the game is in fact
over if the move is winning so let's
just run that real quick
python run current file okay player one
make your selection three
yay it says player one wins and we i
guess accidentally printed the board out
one extra time but you know we did get
that functionality it did check that
horizontal wind so i think that looks
good
obviously
um
you'd want to test these like very
thoroughly
but for the sake of the time of this
video i'm going to just start going to
the horizontal the vertical location so
think about where vertical locations can
start
um
can start
we need four up so it can start it's
pretty much the opposite of the
horizontal so vertical could start
all of this bottom section because we
need four up but it can be in any column
so it's gonna be pretty similar to the
last
loop but we're gonna have to change the
row
so you'll see in a sec shift tab tab
we're gonna have to change
instead of the column count doing uh for
c and column count minus three we're
gonna have to do row count minus three
because we can't start at the top row
and then we're gonna have to add these
pluses to the rows actually
row plus one
row plus
two and the last one is
row plus three and
once again like
see if you could figure out how to
manipulate this
um these equations to work for
any length of a board and also let's say
maybe we wanted to make a game that was
like connect six like it would be a cool
challenge for you guys to try to
build these functions so that they could
be any
number of columns any number of rows and
any number of
pieces for the winning length okay so
let's check to see if the vertical
locations now work we're going to run
this again
real quick
so tools
python
current file
three
cool it works again so we see you have
the four in a row with the ones right
here and it says player one wins
congrats
so that looks good
uh now we have to get to the little bit
of the trickier
um
things we're gonna have to check for the
first we'll check for the positively
sloped diagonals
and we're also going to
make a separate method to check for the
negatively sloped
and you'll see why we need to do this in
a sec diagonals
all right so let's think about it we're
going to think about it the same way
where are our possible starting
locations
that we could have a positively sloped
diagonal
well we can start here and go up we can
start here and go up here and go up
so i think the last piece we can start
here and go up so this is going to be
the top row
and we can't go any farther than this
piece right here so that looks like
we're doing
row count minus three and column count
minus three
so
all right
so we're gonna we'll just copy this code
see oh no what happened
see and i'll paste that in right here
all right so we're gonna have to
subtract three from column count and
from row count and then how this is
going to increment is you start with
that initial starting location and then
we need to plus one
to both things because it's a
slope it's not just a horizontal or
vertical now so we have to
do the addition step for both of these
okay cool and as we've been doing let's
just check to see if we can get a
diagonal win here
so player one maker selection i'll just
start in the
all right we're almost there
uh so close
don't screw this up now keith okay and
we'll check here
cool the diagonal there worked so that
looks like it's working too
and then finally we need to do the
negatively sloped diagonals
and so if we think about negatively
slope diagonals they can start at the
top and go downwards
but they couldn't start any lower than
this right here this is the the last one
they could start at because they have to
go down four
so
that looks like it would be
the top rows
and then also
the
columns minus three so we're going to
start the rows at three
and we're going to have to start the
columns in the normal normal location so
this is going to start from
three to
the row count
and so it's three because
if you think about it z this is the
zeroth row
this is the first row second row
third row so even though it's actually
the fourth up it's third index so that's
why we're starting at three
and that's going to go all the way to
the top and the column count is actually
good as it is and so this is going to
have to now go
it's going to go
positively over in the column direction
but it's going to go down a row so
negative 1 here
negative 2 here
and this is just a negative slope you
you know you have one direction positive
one direction negative
and this will be
negative three so let's test to see if
this works come on
rpl python
current file
okay
we'll just build up the left side first
okay
two
okay
okay okay okay we're almost into the
negative diagonal there so player one
you can go three
and then player two
two and then two
cool the negative diagonals work now too
okay so that looks like we have all the
possible winning directions you should
more thoroughly test to make sure the
all the edge cases work but to me that
looks pretty good so we're also going to
implement the functionality for
player 2 in this main game loop
okay so this is player two
player two wins congrats game over true
okay
and if you wanted to you could just
break out of the
the loop
if you didn't want to see this board and
the turns changing at the end okay so
that's
we've now finished the
command line version of the game
so we're going to take this game
and we're going to expand on it to
actually make it look nice so the first
thing we're going to do to do that is
import a library called pie game
and just like the numpy library if you
don't have pi game installed just open
up a new terminal window and type in pip
install pi game
as you can see i already have it
cool
all right and now what we're going to do
is we're going to have to start out by
initializing pot pie game so this you
have to do in any pie game project so
before our game loop starts we're going
to do pie game dot init
okay
and then what we're going to have to do
is define our screen size how big do we
want our game to be
so
if i real quick just build the finished
version i have
you can see that you know it's
pretty
you know you can kind of break this game
down into squares i would say you have
squares that represent each column in
each row
and then i have this one extra row at
the top
so we're going to define each one of
those squares
as
100 pixels so
the sizes we're going to talk about
right now are all in pixels so the
square size is going to be 100 pixels
and then our width
for our screen is going to be
the number of columns so the column
count
times the square size
cool
and the height
is going to be the row count
times the square size
and actually if you saw my
the game i just dragged in i'll drag it
in one more time
i actually added one additional row
because i wanted this spot where i could
display this circle that i'm dropping
so we'll actually make this row count
plus one times square size for the
height
and that will be packaged together
nicely in a variable called size which
will be a tuple of width comma height
and then to get pygame to actually read
that we need to type in the following
screen
equals pie game dot display dot set
mode
and then
we'll
have it read in the size
and if you're wondering where i'm kind
of just magically getting these
functions from i'm looking at the
documentation on the pi game site so if
you go to pygame.org docs you can find
all the kind of functions that i'm using
i'll post a link to that in the
description
i'm going to real quick test to see our
screen is actually working so you can
just
run control b
and as you can see the window popped up
and then it disappeared we'll handle why
it's disappearing in a second
so it looked like though it is reading
in that screen
cool so let's now create a function
called
do a couple things
so i think first we'll define a function
called drawboard
and this will just be like print board
that we defined up here but now we're
actually going to draw it with the
pi game graphic so draw board is gonna
have to take in the board and that's
about it and i'll actually pass this for
now because we're gonna make some
changes to our loop before we
do this draw board
so the first major change we're going to
do to our loop
is pi game is an event based
game library
so pi game kind of works and allows you
to function in the game by just reading
all of your movements of your you know
the keys you press the mouse buttons you
click the mouse like how you move your
mouse it reads those all in as
individual events so that looks like
something like this so for event
in pygame dot event dot get
and as i just said events are like mouse
motion mouse button down key down
etc
so we're going to read in we're going to
drop a piece by clicking down so that's
one of the important events we'll have
to get
so we're going to first do just kind of
follow me on this one event type
if event type equals equals pie game dot
quit
so this is just something you want to
handle in all of your games that you
make
just allowing your game to properly exit
out if you click the button here in the
top right that x out x is out of it so
if that happens
we have to do a system exit just so it
properly shuts down
and to get this cis right here we're
gonna have to import that into our
project as well that means system and
that comes default in any python
installation
okay
system exit now to get to the more
interesting stuff
the event that we really are gonna care
about to start is
mouse button down so if event dot type
equals equals pie game dot mouse button
down and all the different events you
can also find on the
pie game website under the docs
the game is going to run by us
clicking down on a specific spot on the
screen where we want to drop the piece
so instead of reading in the column we
want to drop it in as we did previously
now this column is going to be populated
by where we click
so i'm going to real quick
put all of this stuff all this behavior
into this mouse button down event type
because now the events of us dropping
the piece always happen when we click
the mouse button down so we don't want
it to happen otherwise we don't want it
to be asking for this input
alright so column equals
and this is going to be where we click
on the screen so just
for now i'm going to
just kind of comment out this stuff just
so it doesn't run on us while we're
testing
control
and that's just real quick see if this
fixed our error of
the screen disappearing right when it
pops up
ah what happened
print
and as you can see now we have this
screen and it's
not
you know it's staying here so that's
because we actually added in this event
loop here
it knows to kind of continue while these
events are happening and the exit out
will be handled properly by this the
system exit cool
all right so
we have our screen looking pretty good
but doesn't have any
graphics obviously
so we're going to implement the
drawboard function now
so if we think about it
i'll drag in the finished one i have
again
we're going to draw
some sort of
rectangle for each of these slots and
then a black circle inside those
rectangles
and then we'll have to draw this
afterwards this piece that we drop and
then whenever we do drop a piece
the the one or two that's in our command
line based game will become like a red
circle or a yellow circle based on
what we're doing so
let's uh implement this
so
first we're going to iterate through
kind of every spot in our board so for
r
or for
we'll say c in
range
column count
and then we'll do the same thing for
r and range
row
count just as we did above here when
we're editing through all the the spots
well
we need to initially just draw it as
like an open
you know a
blue blue rectangle and then in that
blue rectangle we want a black circle so
we're going to
do a pie game.draw function so first
we're going to draw a
blue rectangle
so that looks like kind of our game
board and then the black circle inside
of that will be the open slot
so we're going to draw that on the
screen and i'm going to drag in again
the
the light the library so i can see
exactly what i'm doing so as you can see
here pygame.dry wrecked we need to take
in the surface the color
the rectangle we want to draw
and then the width
so
the screen is the surface we want to
draw it on the color is we want a blue
color so i'm going to define blue as a
global variable a global static variable
up above this is going to be an rgb
value so we're going to say it's 0 0
comma 200 and that means or 255 or so so
that's going to be a very blue
um
rgb value because this means red this
means green and this means blue and the
only color that's
actually has some value is the blue here
so the color we're going to say is blue
we just defined that that's the rgb
value now we need to find our rectangle
so our rectangle
is going to be
the you need to have four different
things to define your rectangle you need
to have
the size of the width and height and
then also the position
so the position is going to be this
might be take a little playing around
with to get this but it's going to be c
times so these are numbers 0 to
you know the column count and zero to
the row count there's gonna be c times
square size
because we want the actual this is the
top left corner of it
and
that's going to the
and then our
position on the y-axis is going to be r
times the square size
and our height and width
are going to be the other two parameters
of this
what that make up a rectangle object and
that's just going to be it's going to be
a square so it's square size square size
height and width are the same
and the width op argument that i showed
was in the documentation as you can see
it's defined as 0 so that's optional i
think that's just the
outline like uh the line that surrounds
the square so we don't need to implement
that all right let's test to see if just
these rectangles draw properly so
down here we'll just do a
draw a board
taking the board
um as we did here and then what we have
to do whenever we want to update our
display is do pi game dot display dot
update and that will make sure that we
actually see what we're supposed to see
so we'll build that real quick
oh and as you can see we have this just
giant mound of blue and the one problem
i see right now is it's not actually
opening up the i wanted the top to be
open so we could have a piece that uh
swings around it so it shows us where
we're dropping it
so i think the problem with that is
because our axis starts at zero zero
we actually need to
to shift down by one square size to kind
of account for that
offset that we left for that space so
we're gonna have to add a square size
here
now we build this again and as you can
see it looks proper
now we'll need to fill in some circles
to represent the
the slots
so we'll do that by drawing a circle in
pi game and that's also in the
documentation so we go
pygame.draw.circle
and that's going to take in the surface
of a screen
and now we need a color
so i think a good color
would be just black so we'll define
black up above too
and black in rgb is just zero everything
zero
zero zero
okay so this is black
and then let's drag in the documentation
real quick to see how we're going to
finish off this circle so circle circle
circle
okay position and then radius so this is
going to be the position of the center
of the circle as you see in the
documentation and the radius will
probably want to be a little bit smaller
than our square size just so there's
the circles aren't touching
so let's define a radius 2.
so our radius is going to be
define that under
the width and height and whatnot so our
radius is going to be
a little bit less than the square size
so
we'll do i'm going to make this also
they have to be integer values i believe
so once we start getting into division
it might get a little bit messy so it's
going to be int square size
divided by 2 because it needs to be the
radius is half the diameter and the
diameter would be the full square size
then we'll just minus an arbitrary like
integer value off of that
so now we can draw our circle with that
radius
but we'll have to do the position first
so the position
where is it i forget oh it's in
dropboard
the position is going to be so if this
is the top left of the rectangle
our position for the center of the
circle is going to have to
be that
and then with some offset
so square size then r times
square size
plus square size
and the offset is going to have to be
like half of it because we're talking
about the radius so half of the
rectangle is going to be
adding an additional square size
divided by 2.
adding a square size
divided by two
all right let's see what happens now oh
and then actually we're gonna have to do
the
actually specify the radius so the
radius is what we defined just a second
ago
build
what happened uh
yeah integer argument expected
okay so it looks like this division
caused us to have some floats in our
code so we're gonna have to actually
make this int
yeah pi game it seems like only accepts
integers so make sure that everything
you
every position and radius
value you make a integer
come on baby let's go
cool yeah we got a board
we'll finish implementing this graphics
we'll implement the piece dropping and
then a nice little piece follower up
here
so to start this video
navigate down to the main game loop
before when we were selecting which
column we wanted to drop a piece in
we mainly typed in a number between 0
and 6 to specify this
now that we have a graphic
we want the column that we dropped the
piece in to be dependent on where we
click so if i click on the left side of
the screen
we want it to drop the piece in the left
column if i click the middle the middle
column etc
so where we drop the piece depends on
the x position
of our mouse pointer
so luckily for us pygame makes
using the getting the x position of your
mouse
super easy
so if you go to the pi game
documentations under the events
it lists all of these events and then it
lists the properties you can get on
these events so for us we care about
mouse button down
and we care about
the position so position gives us an x
comma y tuple
of where we clicked
and i can use that as follows
so i can do print
event dot position
and then i can rerun our game and so as
i click on the screen you'll be able to
see in the bottom left the
positions where i'm clicking so if i
click in the top left of the screen it's
about zero comma zero that's where our
axis starts if i click on the bottom
right of the screen that's the
the full dimension of our game and we
specified that to be 700 700 so these
are the pixel values of where we're
clicking
to develop a
kind of way to select the column based
on where we click we need to try to find
a pattern on clicking in these different
columns so i'm going to do that real
quick
and if we look at all these clicks i
just made we can see the first click is
between 0 and 100 second click is
between 100 and 200
200 and 300 etc so the last column is
between 600 and 700 so we can somehow
round these numbers down to just give us
zero to six we're back at where we were
when we mainly typed in those numbers
so we're going to do that real quick so
let's we can go ahead and uncomment
all this code and actually this is
supposed to be a comment so we can
uncomment
this code right here and we can just
comment this out for now
so
column so we want that to be
we'll say that the x position so this is
a tuple in the x values first so the
position of x
is equal to event dot position and then
it's the zeroth element of that
the column now is going to be so this is
between 0 and 700.
so the column we can get using we're
going to also just to make this our
lives easier we're going to import a
library called math this comes default
in any python installation
so we are going to get what we want to
drop it by doing
position x
then
we're gonna divide everything by a
hundred because this would give us a
range between zero and seven instead of
zero in seven hundred so the first thing
we're gonna do is divide it by a hundred
and a hundred remember is what we define
our square size sizes so to make our
code a little bit more robust to changes
we're going to do position x divided by
square size
and then we want this to be a whole
number an integer value so we're going
to have to take the floor of this
division so that will round it down to
the nearest integer so we're going to do
math.floor
and then the final change we're going to
have to make
is we just need to make sure that the
column is an integer
because we don't we can't take the index
of a float value of decimal value so
we'll just
ensure that it's integer by just
surrounding it with an int
and now we should be able to see when we
click on the screen we should see our
board building up and we can copy the
same thing for player two
and we'll uncomment this
comment that
uncomment all of this and then we'll
make player two be able to select the
piece in the same way so
we'll say position x equals event event
opposition zero
and then
the column
now
oh my god messy
okay we'll delete this line cool so
let's see what happens when we build the
game
so now we have this uh where's the
actual game window what happened oh it
like didn't pop up for some reason
so click down the middle
if you can see over here in the bottom
right our game did pick up that click so
i click on the middle again
keep clicking on the middle and it keeps
reading that i'm dropping the pieces in
so that looks really good now we
actually have to just represent that on
the screen
so to do this we'll just make a small
change to our
draw board function that draws the
graphics
so navigate to drawboard
and we'll just do a if statement here
just say so the rectangle is always
drawn the blue rectangles that make up
the the board the black circle
represents the empty square so
if
board
i mean uh
board
row
column
equals equals zero then we want it to be
a black we want it to be empty
if
else if board
our
row column so this is just indexing our
matrix equals equals one so that's what
we see here player one dropped it in the
middle
then we want to draw a circle so we can
just copy this line because we know this
is in the right position
but we're just gonna have to change the
color up
so
we don't want it to be black we'll just
use red and yellow player one will be
red so this is going to be red
and this is not a built-in thing we're
gonna have to define red
so we'll define red right below black
these are rgb values so r needs to be
have a value and the other two can be
zeros so this will give us a nice bright
red
and then while i'm up here doing this
i'm also going to define yellow
yellow is both red and green it's a
combination of both red and green and
rgb so 255 235 0.
so now we have red and yellow for
player 1 and player 2.
where was that
okay yeah it's red and then one last
line
which will be
the else condition that'll be if board r
comma or r c is two
so that's going to be pi game well
actually i'll just paste this in again
pi game and then instead of black
we'll make this one
yellow
and then one thing that might not be
intuitive is that whenever we
make changes to our
game board
after this is all done this loop has
been iterated through we're going to
want to call
pygame.display.update that will
re-render the screen with the new
changes
so let us let us and also we're going to
have to add
the drawboard we used we were printing
board on every turn but we're going to
draw a board
here as well
okay moment of truth clicking right here
no what happened
so it looks like it's populating it's
just populating it in the wrong spot
and the reason for this is because of
how our axis is set up
so
as you recall when i click down on the
top left this is the zero zero
and this is the 700 700 space
so
in our game though this is the zero zero
piece
but it just kind of flipped so when we
printed the board we called that np.flip
function so we're just going to have to
figure out a way to offset
this to actually be on the bottom of the
screen as opposed to the top
so
to do that
we can just
use our height smartly so what we really
need to do is we're starting at the
bottom
so we need to subtract whatever we're
actually trying to build up from the
bottom
from our height so height
minus this
height
minus this let's try running this
what is happening
all right
so we still having our issue and the
reason we're now having an issue is
because this
piece right here is still filling in the
old fashioned way so they're kind of
like filling in black and red and yellow
tiles all on different axes
so what we're going to do make our lives
easier
is we're going to
take out
these two lines into another loop
so i'm going to delete those real quick
and
we're just going to do a whole another
loop
of so just try to bear with me here i'm
going to copy this stuff we're going to
iterate through everything again
this might not be the smartest way but
it's just going to be very clean for us
to deal with because we're always going
to
build our
we're always going to build our
background and then fill in the piece
afterwards as opposed to like try to
fill in our pieces as we're building the
back round
so i'm thinking this will work well uh
this spacing is just messing me up and
these lines are so long
there we go
okay so
if board rc is one we're going to fill
it with that
then we can just delete this line
bring this back
okay so now we have two loops running
but this will kind of
fix our problem of
them
building our board out on different
axises so let's try running it again
what the heck
if board rc equals one uh we're gonna
have to make this an elsif otherwise
it's gonna fill out the board uh
for all the empty spaces at the start of
the game equals two
all right
cool let's see what happens now
it looks like it's working properly but
it's just offset by one
square size and that's because of this
right here we are initially accounting
when we're building downwards we're
initially accounting for this but now
that we're building upwards we can
delete that from it
from the height so we're going to delete
this square size here
we're going to delete this square size
here
and we should now fully have it working
build
yay it looks pretty good huh
all right cool so now that we've pretty
much fully implemented a game with
graphics we're going to add a couple
additional features so the first feature
we're going to add is add this little
scroll wheel so that before we drop a
piece we can see what color the piece is
and where we're going to drop it so to
do that we're going to add a new event
we're going to track a new event
and that's going to be the event type
equal to pie game dot mouse motion and
once again all the different events you
can use are listed in the
pi game documentation
and just like
mouse button down
the
mouse motion also has
a position property so i can do position
x equals event dot position zero so this
is going to get me a lot more events
though because it's always tracking
whenever i'm making any motion
so this is going to be constantly
updating so now we're going to use this
position
and
draw some circles based on where that
position is so if the turn
equals equals zero
that's a player one's going then we're
gonna do pygame dot draw dot circle
screen
to the surface color is red because it's
player one
um
the next thing we need to put in the
circle is the position so the x position
this is the center of the circle it's
going to be at position x wherever our
mouse is
then we just want it to be offset enough
so that the full circle can draw so
we'll just make this
square size
divided by two
and then finally we need to specify the
height of
or the the radius of the circle and
that's just the radius we've been using
for all the tiles
else
this means it's turn equals equals one
it's player two's turn and we'll just
copy this
and draw it
and now it's going to be actually yellow
so let's look what that looks like if we
build that
all right
build
oh okay i forgot to get the display
update just like we did in
the draw function so
pygame.display.update
build
oh it looks good but it's just not ever
deleting the circles so what we're going
to do to fix this is right before we
actually
draw the circle we'll just draw a
rectangle that's black that will black
out any previous circles that we have
drawn so pygame.draw.rectangle
surfaces of the screen
color is black
position is going to start at the top
left so that's zero zero
it's going to have width the whole width
of the screen and then the height will
be a square size because that's how big
that buffer bar kind of at the top is
and
that should be good
i think i might have one extra no oh
yeah i have one extra
parenthesis there
yay looks good so now we have this game
over drop
drop
that looks good cool
and so one thing that you also might
want to change is that if i win the game
so i'll win the game real quick with red
it automatically closes right away so
one thing we can do
is we can add a weight pi game has a
built-in weight
function so what we can do is if the
game over condition is true so if game
over we'll call pygame.time.wait
and this is the milliseconds you want to
wait so 3000 would equal three seconds
so if i run this again
one
two
three
it'll shut down automatically
cool
and then right before it shuts down we
wanted some notification that the player
actually won so initially we were
printing it but now we'll actually
render the print function on our screen
so that will look something like
as
follows so we're going to
delete the line that says player 1 wins
and we're going to initialize
a font up top so that will look like
we'll do it right below the first update
so we'll do my font equals
pygame dot font dot system font this is
all in the documentation i'm just
copying some previous code i wrote
and the last time i wrote this i'd use a
font called mono
but there's other options you can look
at the documentation for all the details
and we'll do font size 75
that's just an arbitrary number that i
found worked and then if we go down
below
to actually render that on the screen
horizontally
i can type the following i can say
label
equals my font dot render
player one
wins exclamation
and then
i believe this one right here that i
just put in specifies the axes
that it's on i'm not actually sure i
might play around with that to check
and then we want the color to be red
because uh it's rendering that text red
because player one one and then what we
have to do to get that on the screen
do it quickly we could also use the
pygame
display.update function but i'm gonna do
something a little different here
i'm gonna do a screen.blit and that just
updates that specific part of the screen
and i
toyed around with these values before i
found that
the xy pair where this will start at the
top left of corner of this text starting
at 40 comma 10 worked pretty well so
let's see what happens when i run that
so we're gonna have red win
player one wins
and
the one thing is that tile gets in the
way
um
what we could potentially do we could
potentially draw another black rectangle
if we wanted to
um
i don't know i'm not too bothered by it
we'll fix it in one sec we're going to
copy this for player two
and i'll say player two wins and the
color is gonna be yellow now
build so what happens if yellow wins
i'm making this so hard on myself
player two wins yay
all right and
maybe what we'll do is at the start of
the mouse button down
we will draw that black rectangle as
well so we don't have that annoying
annoying tile getting in our way so
right before we click the mouse button
down that will make the thing disappear
run it one more time
player one wins it looks good and you
can mess around with that as you see fit
okay i mean that's like a pretty
good game i'm pretty happy with it if
you have any questions about it leave a
comment below
peace