hello world this is cs50 on twitch my
name is Colton Ogden and today we're
going to journey back into game
development these last few streams have
been sort of cater towards web and
actually David and I did one on the cs50
sandbox yesterday so if you're looking
for a quick way to spin up a coding
environment in the web browser go to
sandbox cs50 io super awesome website
that we talked about yesterday
so today we're going to go back into
game development the last game that we
did actually was minesweeper I think
which was I think over a week ago might
have been two weeks ago actually we been
doing a whole bunch of different stuff
actually a lot of web development but
indeed we're going to go back into games
today so I'm going to switch over to my
computer here we're gonna be using love
to DS so if you're not familiar with
love it's an awesome 2-d game
development framework you can go to love
to the org and download it for your
operating system they have a quite nice
availability for on Windows if you're on
Mac if you're on Linux and some other
operating systems we've done a lot of
streams on this in the past so
definitely check out our prior playlist
on other games minesweeper was the last
one we did that in love today as well
today we're going to be doing a card
game we're gonna be taking a look at
solitaire and I thought I would pull it
up here just we can see what it looks
like it looks something similar to this
where you're essentially given a deck of
cards a standard 52-card deck you have
normally seven piles here which are I
don't think the technical term is
tableau I think tableau refers to the
portion of cards that you have actually
revealed and set on a given row or a
given column in this case and then you
have the four what are these called I
forget what the exact name of these is
called
do you happen to know you know what the
what the name of these is called the
four sections we're joined today by in
in the back who's kindly helping us get
everything set on all of our platforms
but the goal is to basically fill these
four sections of the top of the board
with all of the cards ace to king of the
different suits so you can see there's
hearts spades diamonds and clubs and if
you're unfamiliar with sort of how cards
are laid out you start with ace
two three four five six seven eight nine
ten and then Jack Queen and then came
and that's the sort of sequence of cards
and all the cards are also given a suit
so you get all of those sequence of
cards in addition they have a suit of
hearts spades diamonds and clubs and
essentially you your goal is to get
though all the cards they're in order
but in order to do that you can lay them
out here in reverse order you know
starting with the top card the king card
going down to ace and you know once you
have all your cards sort of laid out in
this way it's very easy to take those
cards and that sort of lay them out in
that sort of ascending order at these
top level here for example this four I
can easily just bring over if I if I had
the three of Hearts here I could bring
that four of Hearts more easily to the
top than if it were in sort of
descending order or rather a sending
order laying from the King down richer
from the ace upwards so thanks to
everybody who's been in the chat here I
have the dialogue here open and jeans
0:02 to saying big up guys is doing nice
work keep it up very much appreciated
Andres here in the chat Bela cures crazy
flock chalene I presume this as a looool
of 2d stream are you using any love to
deal I berries like love frame or is it
just going to be done from scratch
excuse me and I just realized I
apologize I had the chat visible on the
screen there but the we are not going to
be using any library well that's not
sure we will be using some libraries
we'll be using the class library from
helper utilities for maximum
productivity which is an unfortunate
acronym I brought this up on multiple
streams you can look that up so if we go
to class helper utilities Lua love
helper utilities for massive progression
sorry massive progression and they have
a class dot Lua here so you can visit
this URL if curious I can actually plug
it here in the chat unfortunately named
but that's just part of the Lua
ecosystem it's a very good set of
libraries I highly recommend using
we'll be using that for object-oriented
programming in Lua
when we've used this on Prior streams
but if you're unfamiliar object-oriented
programming basically lets us instead of
using raw numbers and tables and those
sorts of variables we can actually model
things like cards and decks and all
sorts of other more complicated objects
that we wouldn't traditionally be able
to get with the language sort of as it
comes the standard language chalene
saying gotta love all the love 2d
library names yes indeed some very funny
names libraries awesome so thanks so
much everybody who's here already I'm
gonna go ahead and just shift this
twitch over here third shift the chat
over here let's get started so we know
the rules sort of at a glance we can see
that we're going to be using cards so
we're gonna need some way to sort of
have cards that are visible in our game
so for this we're probably gonna need
some sprites so we can go to something
like open game art org for instance I'm
gonna go here open game art org is an
awesome website that I use in the games
class that I teach so this is cs50
EDX org slash games which will allow you
to go and learn game development from
the beginning so you can learn pong we
go up to flappy bird match three super
mario brothers all the way up to unity
stuff actually and in that course we end
up using a lot of open game art org
stuff excuse me for just one second let
me make sure everything is okay
I apologize let me just make sure my mic
it's good on battery but I just want to
make sure that it's a hundred percent
okay for the rest of the stream because
this one's gonna run a little long so
give me just a second you might hear me
cut out my audio
all right we should be back up with
fresh battery so awesome want to make
sure we don't die suddenly on stream and
everyone's wondering why I'm completely
gone quiet
awesome so David's in the chat everybody
shout out David David J Malan to de
stream yesterday on the sandbox cs50
sandbox which sandbox s5000 if you're
curious allows you to spin up a
temporary programming environment from
scratch which has a lot of awesome
pre-installed languages and environments
and libraries and stuff so definitely
check that out if you didn't watch
yesterday's stream and if you have a
large yesterday stream definitely do so
so that you can get a sense of just how
it works and the things that you can do
with it
so open game art org as I was saying
earlier is a platform a website that has
a bunch of completely free gamer game
programming artwork sprites and 3d
models and also things like audio which
can be kind of important too if you're
not a sound designer and maybe you want
some free audio assets you can
definitely check that out but what we
want to do is I don't want to make a
bunch of cards from scratch because when
we did minesweeper I ended up doing a
bunch of sort of making mines from
scratch and that was okay it was a
pretty simple set of sprites to develop
but cards a little more complicated and
they all have suits and I don't really
want to be bothered with actually making
it and I kind of want to make it look
nice to begin with so I know that there
is a pack of nice-looking cards that we
can use here so if I go over to I'm
gonna type casino I ended up looking at
this in advance just to sort of pre
curate the kinds of art packages that we
might want to use there's a nice package
called board game pack by Kenny and
actually Kenny is a artist that I use a
lot in the games course who kindly makes
a lot of his artwork available here for
free so I'm clicking on the board game
pack and this I I think is actually a
fairly high resolution piece of artwork
yeah there 68 playing cards they don't
necessarily specify the resolution here
but I'm just going to download it
there's a link right here most of the
artwork as I said on this webpage is
very kindly
available in this case you can see right
here the license is public domain which
is really cool and answer a great
barometz the topic today we're going to
be implementing the game of solitaire so
you can see here if I go back to this
page the game solitaire is kind of a
classic card game that was popularized
in the gold rush age in a sort of in
Canada in America back in the late 1800s
but essentially it revolves around you
getting a deck of cards you lay out a
bunch of cards sequentially starting
with one cards two cards three cards
four cards most of which is actually
unrevealed at the start of the game and
your goal is to get essentially whoops
that was an accident your goal is to get
all of the cards in the deck from Ace to
King up here on these four sections and
they're all suited to so you get ace you
get your hearts cards your spades cards
your diamond cards and your club cards
and another important thing to actually
is as you're laying cards out in these
stacks here where you're trying to lay
them out sort of in a descending order
where you start with King and go all the
way down to Ace you want to make sure
that they're all in black red order so
notice here in this particular area you
can see that it goes black red black red
black red so king queen Jack ten nine
eight so not only do they have to be in
descending order proper order but they
also have to be cross colored they have
to be in a in a pattern that's sort of
pattern and you have seven sort of
sketch areas I guess you could think of
it as in order to lay things out and
they're called the tableau is the term I
believe for the set of cards that you've
laid out and any one of those given
stacks alright so let's go ahead and
check on that pack let's see what we
have to work with so we're gonna
download this these assets we're gonna
get a bunch of folders here so I'm gonna
look in the probably in the PNG folder
for the cards and the nice thing is they
actually give it to us they give us card
backings as well which is nice because
we will need to show some of the cards
as hidden well see let me see if I can
actually pull up an example of what the
solitaire
looks like when you first start out the
songster selector starting layout so
this is great so this is exactly what it
looks like when you first start out and
this is actually playing a version where
you lay three cards out at a time from
the deck and we're just going to be
doing one card at a time which is more
of the windows version of how it's
implemented and also a little bit easier
to win I think you have a 90 something
percent chance to win as opposed to a
75% chance to win but these are the four
decks where you're supposed to lay out
your cards from Ace to King in the
different suits
these are you're sort of starting
staging areas and this is all completely
randomized it's all drawn from the deck
you start off with one card face up then
you start with two cards the top of
which is face up and the bottom the rest
of which are face down the same thing
happens here then here then here then
here then here you only get one card
face up all the rest of the cards get
face down and then here's your deck and
then here's the one card that you get to
draw from the deck at a time to place
down either on any one of your staging
areas or if you happen to get an ace or
if you've laid an ace down and maybe you
have laid down some other cards in your
for sort of deck areas you can place the
card there and we'll sort of see how the
rules work out and mess around with it
but this is the starting layout this is
what's going to look like and as you can
see per what my prior note was we are
gonna want to display cars that are
facedown so not only are we gonna want
to show face up cards but also have a
card backing so that we know we're
drawing a card or we don't know what the
card is yet
so kind of an important consideration
let me go ahead and check back on that
so we go over here I can see we have all
the cards the individual cards which is
great so we will want that we can see
that they're numbered are labeled in a
pretty consistent way so we see card
clubs 2 3 4 5 down to a Czech king queen
it does the same thing for diamonds and
hearts and spades so that's great
the resolution of these is it's not
showing because my Finder window is too
small so 140 by 190 which might be
actually a little bit too big especially
if we're running it in 720p we might
want to end up down scaling
a lot of these excuse me and actually
does we get are we given a sprite sheet
we are given a spreadsheet so let me see
do we have the cards laid out playing
cards dot PNG which we do have a sprite
sheet here it's 1024 by 2048 so if I
load up the sprite sheet this is an
important thing you want to consider
first of all using sprite sheets is
there any more performance than loading
individual textures because your
graphics card only needs to reference
one file is that at multiple files
multiple locations in memory this is
also a lot easier if you want to for
example downsize this so maybe I want
this to be smaller rather than scaling
it in hardware I can instead just pre
downscale everything and make a smaller
texture so we can definitely do that and
I think that's probably what I'm going
to end up doing so this is 1024 by 2048
it looks like what I can do is load this
up into well first of all let's set up
our project and we can worry about all
of that I'm going to create a new Finder
window I'm gonna set up my project when
a J Harvard dev in this case over two
streams I'm going to make solitaire I'm
gonna load this into V s code and let's
make sure this is blown up so it looks
nice I'm going to create a new folder so
this is my project folder and love to D
what you typically want to do is have a
project folder within which there is a
single main.lua file this is the entry
point of your program much like it is in
for example C where you have int main
void in Lua you have a main dot Lua so
I'm gonna create a main dot well this is
a folder first I'm gonna create graphics
then I'm gonna create outside of
graphics a new file called main dot Lua
which later will fill with our source
code in advance I know this is going to
be a relatively not super complex code
base but it's going to have multiple
modules so I'm going to create a source
folder which is going to contain all of
my Lua files in the future and within
graphics this is the folder that I
actually care about right now I want to
copy and paste from here playing cards
epi
gee I'm gonna bring it over to my
graphics paste that right in there
and I'm gonna open this in ace sprite
which is a graphic editor that I like to
use which has pretty good sprite artwork
support and now what I'm gonna do I'm
gonna just kind of shrink it a little
bit I don't mind how it looks here
actually you can see that I kind of
zoomed out and gave it a more pixelated
look and so this is kind of a preview of
what it'll look like when we actually
downsample everything and it looks okay
honestly it doesn't look bad at all so
I'm not sure what the resolution is at
this point I think I subtracted it or I
choked it down by half twice so if I
were to let's say sprite size lock the
ratio let's let's shrink it down by half
right okay neighbors nearest neighbor
filtering and so this is actually what
it looks like at native size so it looks
okay it's not too bad you might be able
to make something work with this now
each individual sprite so if we're at
512 we have a total of not quite it
doesn't quite divide evenly into 512 so
1 2 3 4 5 6 so if I actually maybe I
crap it don't want to crop it
No maybe not I think we'll end up doing
instead is just because I think I think
if we just use the algorithm we've used
in Prior streams where we sort of go
throughout the spritesheet figuring out
the size of the cards we want and maybe
actually don't even go through the
entire sprite sheet just extract the
cards themselves and sort of forget that
there's whitespace it won't even matter
too much so in this case we only really
need to worry about how big each
individual card is we'll see this in
code here in a little bit but let's go
back to the actual cards themselves
figure out how large they are the
individual cards themselves oh also
another thing that I'm realizing here it
doesn't include the card backing in the
sprite sheet so we're gonna have to load
that texture separately that's fine it's
not a big deal it's only one individual
sprite let's see the cards themselves
were 140 by 190 we shrunk it down by
half so they're actually 70 by 95 now
which is the one consideration we need
to be conscious about is the fact that
when we end up stacking things we could
have theoretically a deck that starts
with a that has 1 2 3 4 5 6 blank cards
and then from King down to ace that
would be a total of that's what 13 cards
13 cards plus 6 cards so 19 cards times
that by well actually we're only
revealing a certain small amount of the
card this is probably what 10 pixels 20
pixels I think we'll probably OB okay
let me make sure I'm keeping up with the
chat here do you did you create this
card sprites too says l1 no I did not
create the card sprites so we actually
got if you go to open game art org and
then go type in casino for example it's
called the board game pack so actually
if you go to the open game art org slash
content slash board game pack here
you'll you'll find it but it's a card
pack or a casino pack generally speaking
by
artist named Kenny who actually really
enjoyed the artwork of and I use a lot
in my games class but he has a lot of
different themed art packs and this
particular one he happens to have a
bunch of cards just like this and I like
the aesthetic they downsample nicely
into more pixelated artwork so we're
using that and right now we're sort of
figuring out how much we can downsample
the artwork so that we can use it in a
smaller pixelated game and have all of
the cards visible on screen no matter
what the deck size or the tableau size
which we'll look at so we're just doing
a little bit of preliminary
investigation here but I think we'll try
this we can always reset all this so I'm
gonna save this so now we've shrunk it
down by half effectively and I'm gonna
go back into here and we can see that
now instead of 1024 by 2048 it should be
512 by 1024 which you can see right here
so this should be a good size and then
we'll end up chopping this up into bits
and pieces in main
Lawal rather in a util down low which
will implement again from scratch Bebek
nice is around 4 5 1795 oh the aspect
ratio yeah yeah yeah on the cards is
that transparency going on with the
checkers background with the checkered
background where are we referring to if
we go back to a sprite Oh with the
checkered background yes yes yes yes
this is transparency so anything that
gets some if we were to import this in
our loved 2d game and render this just
like completely flat it would not render
anything here just the cards themselves
and I actually think that there might be
a line of transparency but I actually
can't tell just by looking at it here
well we might end up seeing it once we
end up loading it into our game but yes
if you're in most 2d sprite or artwork
programs Photoshop a sprite in this
case you'll typically see checkered
background when you load in an image and
that just means it's completely
transparent if you were to draw that in
your game it won't draw anything Oscar
em says howdy hello Oscar him and then
the true true Kenny's kindly plug the
link to the sprite artwork cool so let's
go ahead and get a little bit of code up
and running
here so I'm gonna do just a little bit
of the typical stuff as we're loading up
a love 2d application so we can get up
and running we're gonna call this
solitaire I am the author and plug my
email address in here this is relevant
for when I end up publishing this to
github which will do so eventually this
will be downloadable you can download
this and test on your own computer I'm
gonna go ahead and do a few preliminary
functions we've seen these before but if
you're unfamiliar these are functions
that the love framework expects you to
have when you start your game so love
that load triggers at the very beginning
love that update triggers every frame
gets the amount of time that's passed
since the last frame so that you can
sort of calculate different frame rates
or different speed computers the same
speed you can have things happening at
the same progress despite what someone's
frame rate might be on their machine
which is very handy if you want this to
be to perform consistently across
hardware and then draw does also operate
per frame like update but it doesn't
accept any frame rate this is just meant
for just pure drawing no changes
necessarily to be calculated therein I'm
going to preemptively sort of get
everything structured in a structured in
a fairly robust way so I'm going to say
require source slash dependencies and
this is important I'm going to go over
to my source directory here at a new
file called dependencies Lua
this is where I typically like to have
all of my libraries and also all of my
textures so we'll do a little bit of
testing here just a sanity check make
sure everything's up and running I'm
going to go ahead and say gee textures
equals a table G meaning that this is a
global variable I should be able to
access it from anywhere this is a sort
of a convention I'm going to give it a
name of cards and I'm gonna set it to
love graphics new image graphics slash
and what is it called playing cards dot
PNG so now this is available anywhere in
my application typically I like to do
this I like to have all of my text
all of my sound files everything all in
my dependencies dalawa this is just a
way of modularizing your code sort of I
forget what the exact term is but alle
it's not allocation of interests it's
there's somebody in the chat might know
what it's called but it's basically just
making sure that all of the things that
are within one domain get isolated into
one area so that you don't have to go
grapping through your entire source code
repository to figure things out so I'm
going to go ahead and love dot load I'm
going to say love dot window dot set
title to solitaire just for quality of
life I'm gonna actually implement
another function here called
love keep pressed which takes in a key
and again this is another function
called by love and it will call this and
it will pass you the key but it's up to
you to define what you should do with
those keys separation of concerns light
of hell one that's what it is thank you
very much love duck key pressed takes in
a key and it love will actually pass the
key for you depending on when you
actually press a key on your keyboard
it's taken care of all that for you
behind the scenes but it's up to you to
say what you want to do with the key so
I can just say if key is equal to escape
call a function called love event dot
quit and I think I actually forgot to
press tab and so it got confused with
the spacing there also thank you very
much to the couple of folks that just
followed I didn't have the list here but
I do now thank you very much to explore
Suraj graphs micros 22 and Jerry bleah
if I'm pronouncing it correctly
hopefully I am awesome so that's how we
end up quitting our application I think
I should be able to just test this now
if I run my project which I just did
with command L I'm using vs code with
the pixel byte Studios plugin for love
2d so download that and you can just
press alt L or command L on your machine
and it will very nicely and conveniently
let you run love without needing to go
to your command line or to drag-and-drop
it to your executable it
super convenient and also thank you to
echos 2165 for the follow so we can see
here at the top of our window I do
indeed see the word solitaire and if I
press escape it does indeed quit the
application so everything is working as
expected I'm going to do a another
sanity check I'm going to say love
graphics doc draw I'm gonna reference
that gee textures table that I created
earlier and I'm going to reference the
cards sprite that we were storing in
that table if you're unfamiliar tables
are just essentially hash tables or
dictionaries or objects from JavaScript
they function identically to those with
a couple of other caveats but this is
Louis way of storing sort of arrays or
hash tables they function in a
multi-purpose sort of way so now if I
press command L we do indeed see all of
the cards that were in that texture
everything is rendering just as one
block obviously we don't want to draw
the textures as they are in this one
block we want to be able to say I want
to just draw the King of Spades or the
six of Hearts at any given point so we
need to do a couple of things before
this is possible and I haven't written
this function from scratch in a little
while so we'll see how effectively we
can do this I typically like to go into
util - I like to make a util module for
utility functions and say I want a
utility function that will take a
texture a sprite sheet as it's called
and chop it up and store it as a group
of separate sub textures in this case
they're called quads in Lua and luck
rather in love 2d this is the object the
way that they sort of idiomatically
reference them but you might see it
referred to as sprites trying to think
of what other words one might use to
describe it texture area text area well
not text area but texture area you might
see it referenced as texture block
texture rect those types of things as a
lot of different connotations but in
utila WA I'm going to probably first
write utility functions and then maybe a
function called I typically like to
generate quads and have it take a
texture and a width and a height and in
this case it's a little bit different
because usually I assume that the
texture fits the dimensions of the oh
well actually no we can do is we can
just say texture with and texture height
and so now in this case I can say
basically G qua G frames will say G
quads just to keep the sort of language
consistent I'll typically create a table
called G quads and I'll say cards I want
it to map effectively to my other
texture I wanna be able to reference my
texture and I want to be able to
reference the quads that I generated
from that texture all the separate sub
textures the individual cards in this
case so I can say generate quads G
textures cards and we saw earlier that
they were what was it we figured it out
it was seven was it was at 70 70 by 95
right yeah 70 by 95 and actually using
these hard coded numbers is a bad design
decision so I'm instead I'm gonna go to
source when you create a new file called
Constance da lua and this is typically
what you should do you shouldn't have
magic numbers sort of all over the place
instead I'm gonna in in here say card
height gets 95 and card well rather
typically width goes first card width
equals 70 and notice that I'm
capitalizing and underscoring these
variables this is sort of idiomatic for
defining a constant so something that
you shouldn't change now Lua is
dynamically typed meaning that I don't
have to say Const card with our card
height or int card height rather it
determines what the value is depending
dynamically on what it gets assigned to
or whether what value gets assigned to
that variable in this case it's getting
the number 95 so it just knows at
runtime
a number and knows what to do with it
what it can do with it will give you an
error if you try to do certain things
with it for example adding a string to
it it'll give you an error I'll crash
your program but there is no typing like
you might see in C or Java so there
isn't really a way to enforce that we'll
use these variables as constants but by
capitalizing them and using an
underscore this is a programmer
convention this illustrates to the
programmer that we should indeed not
change these variables at any given
point in time so if you see that
typically don't mess with the variable
naming I could absolutely do that it
would just sort of break the sort of
implicit handshake that I'm making with
myself which would not be good but now I
can say instead of 70 and ninety five
card width and card height and things
are a lot more readable now I can tell
that I want to splice this texture this
card texture on my card width and card
height and not some random value called
70 and 95 which had no real meaning
prior to this point so now I actually
need to implement the function currently
it's an empty function so I'm gonna end
up needing to return a table of quads I
know that and we can go to the love 2d
documentation actually and see what a
quad is soul of 2d quad this is
important basically a quad is just a
rectangle in this case a quadrilateral a
polygon with four sides and four corners
with texture coordinate information and
you know you could define it as a square
you can define it as a rectangle of you
no longer width and height or longer
height than wit and that's what we're
doing in this case we're actually
defining quads that are sort of longer
tall you know taller than they are wide
because that's how cards are laid out so
we care about where we want to define
the corners of our quad right we want to
make sure that we say give it the XY
position but also make sure we say how
tall the quad needs to be and also how
wide it needs to be and then we need to
offset that row by row in our sprite
sheet and by generating these rectangles
sort of one by one if we look at the
sprite sheet one by one he
right by going into this and sort of
creating a rectangle here in a rectangle
here and a rectangle here sort of an
invisible rectangle we can tell love 2d
when we draw given that quad just the
area defined by that quad which is
really nice and this is how you get
sprites from a compounded sprite sheet a
more complicated drawing that you maybe
want to put everything inside of instead
of having separate individual sprites
which we very could which we could have
very easily done here we could have
easily just drawn these individually you
know the four five six of Hearts etc the
problem is if you want to downscale all
of these now we have to individually go
in and you know maybe import these into
a sprite / - sorry save it gets kind of
bulky we could automate this with a
script but it's typically more idiomatic
and game development or can some more
common to use a sprite sheet so back to
our code I can say in generate quads I
know I'm gonna want a table to return
right so I can say local quad table gets
an empty table I'm gonna return quad
table at the end and local just means
this is a variable that exists in this
function don't make it globally
accessible if I make it if I just say
quad table the way the Lua works this
quad table variable will actually be
available anywhere in our application
which is not generally good engineering
wise very easily could you clutter your
namespace your global namespace
basically all of the symbols that your
program is referencing all the variable
names you can very easily make this very
large and very hard to track where each
variable is coming from by not using
local where you need to so definitely
use local where it's appropriate in this
case we only want quad table accessible
within the context of this function so
we're only going to reference quad table
by using local so let's figure out so we
need to generate a quad which is an x
and a y in a height and a width
throughout our sprite sheet so I can say
local X is equal to 0 and Y maybe is
equal to 0 as well this is where we're
going to start
this is the pixel sort of right you know
right here at the top left that's where
we're going to start our function to
splice the spritesheet so I'm going to
say for wha I guess for Oh actually what
I can do is say for Y is equal to zero
until and how many cards we have one two
three four five six seven eight nine ten
so we have ten cards so that's up until
[Music]
it's not going to quite be Y times it's
not going to quite be ten times 95 it's
actually gonna be ten times ninety five
s gonna be nine times ninety five so we
can say is in our sprite sheet want to
say card or card sheet tall gets ten
card sheet wide gets oh and actually I'm
realizing an issue here the issue is
that we don't actually have a consistent
sprite sheet we have five notes that we
have five rows here but we have I'm
sorry five columns here but four columns
after after Row three so starting in row
four we actually have only five columns
so I think it actually makes more sense
to start top go down and work our way
vertically through the spritesheet and
stop when we get here I think that makes
a lot more sense and actually our things
laid out in a consistent way things are
things are laid out wait are they no
they're not actually laid out
consistently that's pretty funny
actually so we started Queen King Jack
ace in spades and it does go down
sequentially and then the Joker
and then the Queen down here but notice
that instead of the two of hearts here
we're actually getting the two of clubs
so they actually made the spritesheet
inconsistent that's funny and it's gonna
screw up our algorithm a little bit so I
hate to spend too much time on this but
and also another interesting thing is
okay they only need one joker actually
that's fair I was gonna say they only
have one joker typically a deck has I
think two jokers or four Joker's but I
should fix this the reason that I should
fix this is because if I want the
algorithm to generate all the cards in a
sequence and I want all of those cards
to I could do this in code is it really
worth it hmm it's good design so I
probably should do it so what I need to
do is go into here and not do that but
take a marquee tool kind of bring this
over here which I think this is correct
and something like that and then if I
come and see this can I move this around
oh I can Oh perfect I could just move
this so I'll move it over here take this
let's zoom in all the way over here is
that too much might be too much oh no I
don't want to I don't want to actually
shrink it let's go ahead and do this
this is correct
think that's correct and so now if I
move this over to where we have our now
our space let's move it down over here
right over here okay perfect and then
now if I bring this also Kenny if you're
watching maybe fix your fix the ordering
of your sprite sheet love the artwork
but I'm not sure why it's out of order
let's go ahead and do this bring this up
here
Mabel P says hello and Hardy price you
can see the size when you select the
cards in the bottom status bar ah good
point I actually didn't think about that
this looks like it should be good this
should work Kai Jean thank you very much
for the follow I think that's right yes
and P me know thank you very much for
the follow okay so we did that I'm gonna
save it so now we should have I think a
consistent deck of cards so what I was
trying to say before before I realized
that the the spritesheet was actually
slightly messed up is that instead of
going horizontal rows you know going you
know row by row well actually go
vertically so we'll start here work our
way down go here work our way down and
this way in our table all of the quads
will actually be in order starting from
you know what I just realized the
Queen's are actually before the Kings
too why why is this out of order okay
that's not that's not worth shoot
because if you were gonna represent the
the cards based on their number I could
just I could do it in code it's not a
big deal but at least now everything is
everything is consistent so we can use
that consistency to do something else
riff Sam thank you very much for the
follow okay so well we'll worry about
the fact that the Queen's are coming
before the Kings and the Jack is coming
before the ACE we'll do all of that in
code we'll resore TEVAR ething it's
important in solitaire that ace actually
comes after two so we're gonna do it
that way instead of having the ace
actually come above clean which often
times you can think of ace being more
valuable than sorry not queen king
rather we'll worry about the fact that
that's all out of order and doesn't
match but everything is now in a
consistent state I think it can quit a
sprite now
I'm gonna basically have my algorithm go
top to bottom left to right and then
when it gets to the two here well
actually it doesn't need to really worry
too much about whether it gets to the
two but it will have up until this to
one two three four five so it's ten plus
three so it'll have forty three cards
that we care about one two three four
five six seven eight nine ten
sorry fifty three cards not forty three
cars
I don't know how to count fifty three
cards - the Joker we don't care about
the Joker and I just realized that that
actually screws it up too so it's it's
great this is the fun part of dealing
with sprite sheets programmatically is
you do run into sort of cases like this
where you have to restructure your data
to fit the problem you're trying to
solve and/or write an algorithm that
consider is the fact that your sprite
sheet is messed up and sort of in code
sorts everything out can we have a four
by 13 or 13 by four sprite sheet yeah
absolutely you could do that but you
want to then in that case that's on you
to sort of manually figure out in your
text or in your graphical editor and so
there's a bit of work that goes on you
to do that now if you're working with an
artist you can tell the artist hey I
want to think about my problem like this
so please layout the sprites four by 13
right which I would actually want that
to be the case
my ideal the way I like to think about
it is having everything in a row and so
having Ace to King going horizontally
that makes sense to me I can easily
parse through that programmatically
generate the tables that I need and get
everything working and linds this point
yeah worry about it afterwards just make
a lookup table that's fair - we can
easily do that and write everything in
code there is a merit to simplifying
your code by making sure your data is
nicely laid out but we're already
spending a good amount of time on that
already so we can we can make a lookup
table and resourcing so the card sheet
wide we're not actually going to worry
well we don't need to worry about it too
much but we'll say it's six wide and so
we're gonna end up parsing our sprite
sheet left to right
cards wide and ten cards tall now
actually no not a consideration there's
extra white space at the bottom but
that's not going to matter for our
algorithm because we're going to
calculate it based on the number of
cards not the size of the sprite sheet
which would cause an issue if we were
doing it just that way so back to you
till you WA I'm gonna say 4y gets zero
well actually 4x gets a zero because
we're gonna do this we're gonna parse it
column by column at the top level of our
loop the inner loop is going to go card
by card vertically and so that needs to
be the inner loop so I can say 4x is
equal to 0 and then X is equal X is less
than cards wide or what was the name of
it card width x card sheet y -1 do Y is
my my text editor is being funky with
indentation so what we're basically
saying here is I'm gonna start at X is
equal to 0
oh and I want to also make sure my step
is card with so basically this is a for
loop that's just saying start at X at 0
go up until X is less than the card
width times the number of cards wide so
minus 1 um so card sheet wide - it's
gonna times that by card sheet y -1 so
it'll take into consideration all of
these cards minus 1 because we don't
care about going past this offset here
we only worry about going up until the
left edge of this card because we're
going to calculate the width and the
height we're gonna add the width and
height too then so PIM analysis hello
everyone thank you for the content to
make it a little bit complicated you can
add some sort of image recognition for
the unordered for this unordered sprite
that would be fancy I don't even know if
I'm qualified to do that but that would
be very fascinating um the three of the
club and the heart are swapped this is
Babic
three of the club and the heart oh yes
yes I think that was the the prior point
that you were talking about yes correct
and also thank you to who just followed
I completely missed that I apologize
that was did I catch riffs on and Kazim
so apologies if I didn't but also Mick G
was taken thank you very much for the
follow-up so we're going sort of up
until the left edge of the last sprite
that we care about so we're starting at
X is equal to zero up until the cards
wide minus one and then we're going
we're also in our inner loop we're gonna
start Y is 0 and then cards tall minus 1
times card height so we can say for y is
equal to 0 Y is less than card height
times card sheet tall minus one step of
card height do y is my editor doing that
today that's so weird
and then I might need to restart my
editor honestly oh you know what I did
start my editor in JavaScript mode I
wonder if that's causing funkiness
anyway or started it with a JavaScript
project I'm not sure if that ends up
screwing vs code up in this case but
hopefully not here's where we actually
need to generate a quad in our sprite
sheet so I can say table dot insert quad
table so we're going to insert into quad
table a new quad we're gonna call it
love the graphics new quad and it takes
in and this is a nice thing about vs
code is it has this intellisense sort of
thing for us which tells us the
arguments that new quad takes so what x
and y which is going to be X Y and then
a width and a height so X Y and then our
width is going to be card width and the
height is gonna be card height and then
that should just work here as we need it
to I think oh and I think the last thing
it needs actually is texture get
dimensions for some reason underneath
the hood when you generate a quad it
needs a reference back to its source
image specifically the dimensions I
don't remember the exact reason why I
looked at the
see code for why this is but you can
look at the quote the codes open-source
for luck 2d so you can look and see if
you're curious I don't remember offhand
exactly why that is the case and this is
taking up a little bit too much room so
we can just do that now this should work
if I go over to main rule for example
and I pass into love dot graphics draw a
quad so if I say gee cards quads 0
rather 1 because remember love tables
are 1 indexed it's a very weird thing
about Lua but normally in languages
arrays and other data structures are
zero indexed in Lua everything is 1
indexed just by default you can zero
index explicitly but it's not idiomatic
to do that it's more an automatic just
to stick with a 1 indexing paradigm so
you know something to get used to as
you're venturing into Lua territory but
now let's see if everything is correct
my fingers are crossed that I got this
right oh I forgot to reference my util
class
so in dependencies because remember
we're requiring dependencies in main da
lua so anything within dependencies that
we require well therefore by
transitivity get required so I can say
require source slash util and Cardwell
and also constants make sure to require
that as well require source slash
constants and well that is what just
happened ok why is it ok I've must have
hit a a shortcut that flips it
vertically at the horizontal I'm not
sure how that happened but we won't
worry about that too much
I'm not running 11 my nope so if I run
this attempts to compare nil with a
number util Lua 8 ok let's see where we
screwed up our algorithm on line 8 no
with a number okay
card sheet wide card sheet tall I have
that right card with card height is it
by chance
everything is source constants a source
you tell which is fine okay this is
interesting so on line eight it's saying
for X is equal to zero X is less than
card with x card sheet wide minus one
which is weight you need to put those
into prints and two a parenthesis here
let's try that I don't know that's gonna
fix it
compare nil with a number okay
live debugging here we go
and also in the event that somebody in
the chat caught the bug before I did I'm
going to make sure that I can visibly
see it fascinating okay so for X is
equal to zero X is less than the card
width times the card sheet wide minus
one which is good let's just as a sanity
check let's make sure all of these
things are running maybe so love dot or
rather let's print card width and card
sheet wide and because by default you
don't actually get print output like
console output in the terminal
no doesn't you till require dependent
Seasons using variables from
dependencies you know increment the
counter or does Lua do it for you you
increment the counter with that last
step so the the little bit here which
says card width this is the actual step
now you could do something like for X is
equal to one until ten do and what that
will do is oh wait is that right wait no
I thought I just had a moment of
Revelation but I don't think I did
actually no you don't do a condition
that's what's getting me confused I
think you it automatically assumes or at
least I thought it didn't take a
condition let's see yeah no it doesn't i
got mentally confused about the fact
that it just kind of assumes less than
and that was that was the issue so what
it did was you basically say from 0 up
until that point with this step go up
and you can specify going down and it
kind of does the same thing it will sort
of know that you're looking for greater
than or whatever so this is what i did i
said card with who x card sheet wide -1
up until that point and then card with
being the step value which is by default
1 but we made it the size of the cards
that we're just jumping in blocks of
space card with minus m Kloppenberg so
it doesn't need to be card with dot dot
dot minus one not card with minus one
because we're starting at 0 so by
offsetting by the card width we start at
the left edge of the next card if that's
what you're referring to but ya know it
was me being silly with my four loops so
i apologize
past aesthetic variables and see if that
passes no i think we figured it out i
think it was just an issue with the four
loops so there's actually no condition
you need here you just need to specify
the upper bound or the lower bound if
you're doing a backwards loop but in
this case you're doing a forwards loop
so it just assumes less than cool so
that works well so now we can visibly
see that we are drawing cards at the
right size so in fact i think if we were
to go here and say 4x is equal to 0 up
until car well let's say
there's 13 cards right so here's another
thing that we need to take into
consideration cards in suit we're gonna
say 13 because you start at Ace and you
go up to 10 then Jack queen king
so we'll say there's 13 cards in each
suit cards in the deck will say there
are 52 we are going to need a deck class
at some point but I can say 4x is equal
to 0 until cards in deck do
[Music]
or rather from one until the cards in
the deck because it's inclusive then
I'll say in here X so now we're saying
basically from one until 13 including 13
draw each card and then I want to
specify a different x and a y because I
want to show all the cards being being
drawn there and also go and Bob and berg
says got my languages a bit messed up
again thought the whole statement needed
to be within parentheses yeah no not
quite yeah I know I even I'm today for
some reason getting my syntax a little
bit messed up it's been you know two
weeks since I coded in Lua and I've been
coding a little bit in other languages
so apologize for that but we'll get back
on track here so let's say I want to
draw them all sort of horizontally so
I'll say X maybe rather X minus 1 x card
width and then we'll just say a 0 for
the Y and if I run this we do indeed see
that we're getting all of the cards
drawing from their higher to lower suit
which is pretty cool or their higher to
lower face value now granted as we
mentioned before there's a slight bug
where the Queen actually comes before
the king and this isn't helpful so we're
gonna need to sort of put this in the
right place and then also the fact that
Joker comes in the middle of the deck
kind of screws up our ordering just a
little bit so we're gonna need to
account for that as well so why don't we
do that
actually should we do that in the deck
class figure that out using our data
structure we could do that right
yeah why don't we do that in our deck
class let's make a deck class so I'm
gonna create a deck Lua deck class and
then I'm gonna say a deck equals class
now this isn't syntax that you get by
default in Lua remember we need to
actually import that library that I
mentioned before so I'm gonna go over
back to I think in minesweeper we had it
so if you saw earlier lookup helper
utilities for massive progression that
library you can get the class Lua from
it I'm gonna go ahead and do that I'm
gonna copy that into my solitaire
library and what I typically like to do
is rather than put it with my other
source files I put it in a Lib folder
and so here I have Lib class dot Lua now
in dependencies remember we need to also
account for this so libraries typically
export all their functions as an object
that you can reference by name so I'm
gonna say class I'm gonna assign it a
global variable because I haven't said
local class this is a global variable
called class equals require lip slash
class now anywhere I can use the symbol
class the word class and this will refer
to the library code that I just imported
and by referencing class here basically
using that classes built-in
functionality to use object oriented
programming in lip and Lua which
otherwise doesn't provide it to you in
the same kind of way it has other funky
ways of doing object-oriented
programming which gets a little bit
messy in my opinion a little bit a
little bit iffy especially if you're
coming from a language like Python or
Java where things are more
classical-style a prototype inheritance
on that a huge fan of but it's hard to
avoid especially on the web
javascript is a prototype based language
they recently added classes in es6 which
is nice
so there are taking steps in that
direction at least in real life and
chess the queen is greater than the king
this is bad ignite i like that comment
the couch ogre isn't a quad now i think
we haven't ignored the Joker in quads
injury you're correct we do have the
Joker in there so that's what I'm
referring to we're going to need to
account for the
fact that the Joker is just kind of an
imposter into our table like we need to
account for that its existence so what
I'm gonna do is sort of in this deck
class I'm gonna need to instantiate a
deck of cards that makes sense that has
all 13 cards for each suit all together
we can make it sorted we can make it
randomized but we need to ignore the
Joker basically that needs to happen and
in order to have a deck actually we need
to work our way backwards a little bit
we need to act and we need to also have
a card class we need to represent what a
card is because cards have some
information that's kind of important to
them namely the fact that they have a
face of value and they have a suit you
can have a queen card but your queen can
also be a diamond or a spade or a club
or heart so these bits of information
are valuable and we need to map this
information to our sprites so that when
when we say we want to draw a Queen of
Hearts we actually end up drawing the
correct card or a Queen of Spades
we want to draw the correct heart they
are the correct card so not the correct
heart in that case that that would be
incorrect so let's go ahead and say
function deck and knit and back to the
card actually that's important we need
to say let's make a card Lua class in
here I'm gonna say card class there's
like shadow on the building next to me
and I thought my vision was going wacky
for some reason I'm gonna say a card
equals class and let's create what's
called the constructor for the card
class and some of you who have watched
us before might know what I'm talking
about some new folks might not know what
I'm talking about
this is the code that's gonna run for
each individual card we create and we
know that each card is going to need a
face so we can say face and let's just
say that the constructor will take in
two arguments a face and
a value right so let's say it's gonna
taste a face and a value and so the self
that face equals face and self that
value equals value is just storing that
information from the constructor into
the card itself so that we have a
reference to it later and then I'm gonna
say card render we're gonna assume that
our card is gonna take an x and a y and
another important thing to take into
consideration the cards in our game can
actually be revealed or hidden so we
want another value we want to say self
dot hidden is equal to and by default
we'll assume that we don't want it to be
hidden because we want to test all of
this for correctness pretty soon here so
in addition I want to draw the card in
the right place now I want to say love
graphic stock draw and this is this is
sort of what we need to think about how
we want to structure our data or our
table that takes into consideration the
layout of all of our cards so that we
can index into our you know whatever
that data structure is based on what's
face might be or its value right and so
I can envision this sort of as a 2d
table actually and I'll illustrate this
in a second but I'm gonna say love dot
graphics dog draw and I know that we're
going to use the cards texture
eventually right we know that much we
have that card texture already laid out
that's fine
but the G quads it's going to be a
little different and actually let's
assume that I'm gonna have G card quads
as a new table we're gonna actually
create this ourselves
and this is gonna be a 2d table that I
can index into based on face right or
I've conflated face and value sorry it
should be face and suit not face and
value face and suit so let's assume that
my or my table is going to be laid out
such that I can have a face that I index
into
so there's gonna be four tables in my
table that are indexed based on whether
it's a got that reversed as well it's
gonna index into the suit so the the
table is gonna have hearts spades
diamonds and clubs as the four top level
tables within that table so we're gonna
have one table within that we're gonna
have and I'll draw this out actually in
here in my utility so we're gonna have a
table that's gonna be called actually
but makes more sense to have this
independencies it's gonna be called G
card quads which is going to have a face
value or a four suit tables the first
one which is gonna be hearts right then
diamonds then clubs and then spades
and what these tables themselves are
going to be in here is all of the actual
those are gonna be the actual tables
full of the face quads themselves right
well they're gonna be face end suited
quads but we're going to layout such
that all of the quads inside this table
are the hearts from Ace to King and here
we're gonna have all of the cards the
diamond cards from Ace to King and all
the clubs cards from Ace to King and all
the spades cards remains to King
therefore we can index into G cards
quads at hearts and then index into that
at the value we want and get the right
card everything is sort of laid out nice
and cleanly so this will actually
eventually work just like that and then
I can pass in X&Y that we pass in to
render here and itself this needs to be
self dot suit is equal to suit
so let's actually clean the data like
that and actually make that data
structure the way we want to in this
case I can probably do it in
dependencies lua right here so
what I want is so let's look at our
let's look at our data again let's look
at our quad or rather our texture our
sprite sheet how did I okay let's there
we go so everything starts off in spades
we know that so we can say from 1:00
until 13:00 I want those to all be added
to the spades the spades table right and
then I can ignore the Joker and so then
from 15 until that would be 28 I can put
those into the hearts and then from 29
until 32 those will be diamonds and then
from 32 and 33 until 56 I think I don't
know if I'm getting them wrong
oh I'm adding 13 it should be inclusive
so minus 1 from all those calculations
and that will be effectively the offset
that we needed by the end we should or
the last value it should be indexing
into is number 53 because this is a 53
sized table we have just the one that
we're skipping but the last value will
eventually be 53 so I can probably
pretty easily just do this down here
after G quads so I'll say allocate all
proper cards to the right sub tables so
and I could have put this into the
generate quads function I could have
made this part of its behavior but then
it wouldn't be I mean it's arguably well
no it's a general-purpose quads function
at the moment if we made it a little bit
too specific I don't think that I think
that kind of defeats the purpose of
having the utility function so if
anything we'd want to make a separate
function for this but we might be able
to just do this in code and well
actually
we might be able to make a function out
of this so let's say function allocate
subtable and it's gonna take in a it's
gonna take in the main table start index
and end index oh and also we want to say
allocate sub table the first argument
should actually be the new table 1
allocate 2 so we'll say new table and so
we can do is say 4 index is equal to
start index until end index I don't need
to restart vs code to stop this
indentation starting to drive me a
little bit crazy and also documentation
is important so given a new table
allocate from start index to n index the
elements located in main table allocate
to it from start index index the
elements located in main table so from
so for index so starting at start index
until end index we're gonna do a table
dot insert into new table main table at
index and what this is gonna do is gonna
index in a main table at our current
index which rivets starting at start
index and just add it's a new table
that's all we're doing we're just doing
it we're just doing a just an insert
adding it to that table and so what I
can do here is say and also notice that
it capitalized my functions in util this
is a convention I've seen sometimes it's
not really hard set you could lowercase
this if you wanted to but I typically
like my capitalized functions my utility
function sorry to be capitalized just to
tell me as the programmer that they are
utility functions if there
meant to be used broadly for not quite
classes which classes are also
capitalized but they function in a sort
of robust generalized way so I can say
allocate subtable from and here's where
engineering is important again
so we'll say where do I want this to be
so spades is first so spades starts at
one right so we can say in constants
spades start is equal to one right
that's fine we don't need to specify at
the end because we know that every from
after every start plus twelve we get the
end index so that's fine so I'm gonna
say after the next one which is Queen we
know that Queen actually doesn't start
at thirteen it starts or at fourteen
rather it starts at 15 so we're gonna
say sorry what was that again that was
hearts so hearts start is at fifteen and
then likewise we have diamonds oh you
know what actually we could do we could
make this we could make this general
purpose okay well get more more flexible
so I could say spades start + cards in
suit plus one there we go so it's a
little bit more robust this way will the
draw function be in the card classes
atom the draw function so the car class
will have a draw function and then we
will reference that draw function from
whatever probably use with play state so
we'll use it from the play state but yes
let's save this so heart start was that
+1 and then the nice thing is I can
actually say where did we go after
Hearts two diamonds so I can say
diamonds start equals hearts start
plus cards in suit which is correct
and then is that right that should be
right right yeah because there's 13
cards in the suit yeah that should work
and then finally clubs start is equal to
diamonds start plus cards in suit so
here we have kind of a nice magic
numberless way of looking at the problem
we're sort of shifting the start of each
of these such that we don't have to
write in plus 13 all over the place we
don't have to sue plus 14 for the Joker
everything is pretty clean I would say
so now we're gonna allocate all the sub
tables so we're gonna say into G card
quads at hearts I can say from G quads
because remember our function signature
is such that it expects the new table
the the table we're taking the sprites
from are the elements from this is
general purpose actually theoretically
this should work for any table with any
kind of data but we're going to use in
this case quad information so G card
hearts at using Jeep quads we're gonna
say the start index is going to be
hearts start and the end index is gonna
be hearts start plus cards in suit we
don't want to do we don't want to do
do we want to do plus cards in suit no I
want to do plus cards and see what minus
one because this if we do it this way
it'll actually because it's an inclusive
loop it'll actually go to add the next
card afterwards after after the end of
the hearts and it'll it'll be this way
for all of them so we actually don't
want that to happen we want two minus
one off of that and so now I can say
hearts diamonds and I'm mapping it to
how the layout is down here in the card
quads it doesn't really matter the order
but in here I need to say diamonds start
and then diamonds start + cards and
super minus 1 and here is going to be we
do clubs of spades
so clubs and then it's replace both of
these with clubs and then spades and
then do spades I forgot to command D
that so it highlighted the next one but
now in theory this should actually be
filling this table each of these sub
tables with all of the suited variables
from our suited cards from from the main
table now the unfortunate thing is that
while we have all of the right suits
they're on the right order so this is
another kind of aspect of solving this
problem so let's see what would be the
best way to solve this so it's going to
here we know the queen is before the
king so we can just swap those and it's
okay if everything's in reverse order at
that point but ace needs to ideally be
after the two well actually no because
everything's it should actually be in
reverse order so if you just reverse the
table
that would actually work allocate sub
table so I want to reverse the tables
and then we want to put the ACE at the
end well
then with the ACE at the end reverse the
sub table and flip the clean and the
King and then shift it up so it's more
easier than just to get the right
indices and plug it in and order so it
might just end up doing that ordering a
simple map the card to a number key
value pair and sort according to the
value yeah no it is I think we'll have
to end up writing a sort function
ourselves I don't think Lua has a sort
function does it have a sort function
Lua
sort function I don't think it does Oh
maybe it does but it expects everything
to be in a table does it take an
anonymous function that we can use to be
to be this sorting function
in this case what is F F is typically
these will take a sorting function so
you can define a function in advance
that takes an element and the table will
apply this sorting function to all the
elements and allow you to have a very
flexible sorting function you can do
this as lambdas in Python for example I
haven't had occasion to do this in Louie
yet so this is interesting let's see if
we can actually do this robustly an
alternative order it says EFT
[Music]
okay so this order function receives two
arguments and must return true if the
first argument should come first in the
sorted array this function is not
provided sort uses the default less than
operation of corresponding to the less
than operator I'm not a huge fan of
their documentation for some of these
things it's a little bit it's a little
bit iffy like where is the F function
that I'm presuming was previously
defined I want to get a sense of what it
looks like well I mean we can worry
about the sorting actually well no
because we were gonna index it from card
to draw it that's the whole issue that
we came across here let's maybe write
another function so we allocated the sub
tables which is perfect and that works
presumably that works fine actually we
should probably test that so if I were
to go into we can test that actually in
main let's go over to main and then I'm
gonna go down here into 4 so 4 X 4 1
cards in deck I'm gonna say G quads at
hearts rather sorry G oh did I call it
card quads card quads so at G card quads
I'm gonna index into hearts at X which
should draw from 1 to 13 and so this
should work I might have forgotten
something yeah G card quads which is a
nil value which in dependencies is
weight hi is this a new value wait what
temp 2 index of global G card quads and
nil value and its use line 14 oh because
I forgot to put this in the before this
okay that's my bad
let's go ahead and do that
and I run it quad expected got nil so
mainland 26 which is G card quads at
hearts X G card okay G card one's ours
attacks bad argument number two to draw
quad expected got nil
did we screw something up with our
allocation cuz these aren't failing
right hearts diamonds clubs and spades
we're filling the hearts right allocates
subtable so as a sanity check what I
should probably do is just print G card
quads hearts and let's just make sure
that it's printing out a table and
actually there's a recursive table
printing function that I really like on
line 14 of the card class oh we haven't
done that yet Bella we're not actually
doing anything in the card class so
recursive table output lua there's a
recursive function I don't feel like
writing it from scratch
somebody wrote a function that actually
okay here we go
so I get a function called dump which
isn't a nice name so this is a recursive
function that should allow us to just
literally dump a table I want to
capitalize it just for consistency and
then it recursively calls itself so I'm
gonna also capitalize that recursive
table printing function and it's on
stack overflow so if you're if you
curious to get it if you're following
along it's here on stack overflow I
typed in what I type in recursive table
output Lua first result it's like three
answers down so right here so now I
should be able to just per the name dump
instead of print I'm just gonna dump G
card quads hearts now I can't do this
with my extension I actually have to go
into the terminal here I'm gonna go into
[Music]
dev slash streams and solitaire and call
love dot and then there we go
it didn't even dump it 70 it's printing
70 and 6 though
are we printing something I don't
remember
I don't think we're printing something I
might have just screwed up might have
just screwed up oh wait no that's not
possible because if it's a table it's
set to output the curly brackets here as
a way of visually illustrating to us
that unless some people are asking still
using value instead of suit now we we
changed that I think shoot I apologize
for this slight delay and the flow here
but this is this is programming so live
debugging which is fun stuff let me go
ahead and figure this out so dump G card
g card quads hearts should be a table
right we've said this to be a table and
if we go into for example well actually
let's do it before and after so we know
for a fact that G card quads hearts at
this point in time is just an empty
table so it should be printing at least
a table at that point so let's try that
it's not printing that okay main 26
is it not even printing wait okay come
on print sanity check okay so it's
printing why is it printing 70 and then
six where did we get that from seventy
and six is go to source constants and
source util did I have a print up here
oh yes I printed up here right okay
let's care to those that was causing me
a little bit of uncertainty and then
back here over here let's rerun this so
we're not getting our table printed at
all okay that's interesting so is dump
not working dump
let's try dumping the value 20 to make
sure this is actually working
dump the value 100 it's not even
printing 100 okay so this function is
messed up for some reason or it's not
requiring it and I definitely saved it
we have a function called dump in here
yeah what in the world well first of all
let me just quit code because I I'm
having a site grep with the indentation
issues have been having let's go over to
let's reload this into vs code
I apologize for everybody tuning in
who's struggling with me at this exact
moment but we'll figure it out yeah Adam
says game dev is tough it's a little
tough sometimes okay so we're getting
Santa check we're not getting dumped why
are we not getting dumped okay oh wait
cuz we have to okay so I'm used to it
normally printing we're not actually
it's not actually printing anything it's
a it's returning a value we have to
print dump 100 so now if we go over here
now we get a hundred so now if I print
or if I put gee card quads hearts and I
run it again it's an empty so we're not
everyday okay so we figured it out the
dump function that we copy pasted it
used and this is what copy paste cuz I'm
just bite you in the butt but it returns
a string it doesn't output a string so
we figured that out we're outputting it
now and we're seeing that debug using
the binary search method if you want to
elaborate on that Babic you mean find
the problem and throw away half of the
try to figure out half the problem I
almost promise that doesn't necessarily
always work because you get weird
problems sometimes
unless you're talking about half of the
code put output statements halfway up
the code which yeah that's that's a
popular technique as well so let's get
rid of this dump statement here it's
here with a sanity check statement so we
are saying the sanity check did pass we
are saying as an isolate the half which
is not working yeah generally that's
what we're trying to do with output
statements yeah so we have this now
figured out the problem is that our G
card quads hearts table is not being
populated with information we saw that
it was an empty table which is not going
to help us much at all what we need to
do is figure out why that's not working
and the reason that's not working is
because we're actually not specifying
the quad the quad index that we care
about
that'll do it
still has an issue but now if we dump
the output we do indeed see we have a
bunch of quads in here notice this so
our table is 13 size 13 we have 13 quads
so that's great that's all working
perfectly fine
however in main.lua
for some reason
from 1:00 until cards in the deck Oh
does it do it that many iterations that
would make sense let's try that that
work no that is all right that's not the
problem
wait so there are 13 we have 13 quads
here we can visually see that that's
great right on main line 26 what it's
saying is that this X here isn't
actually being recognized even though we
just saw that it is recognized
hearts does have 13 quads we can
visually see that here we can visually
confirm 1 2 3 4 5 6 7 8 9 10 11 12 13 13
quads so that's they're definitely not
nil right
[Music]
unless okay print X what's printing 14
okay which I did minus 1 though and that
still caused an issue right wait
but cards in deck -1
[Music]
oh I feel like I'm going a little bit
insane here okay cards in deck but if we
pass in five
it goes up to five cards in the deck is
13 right
this little bizarre very clearly we can
see that when I type in fought the
number five okay so here let's let's do
this let's say in Maine let's say from 1
to 13 okay we saw that oh wait not cards
in the deck cards ins not cards in the
deck cards in suit cards in suit oh man
that's beautiful
ok yeah truká nice I for some reason
thought I was doing cards and sued not
cards in deck I'm silly I am just silly
okay beautiful that works great
everything's great everything's
beautiful those are those are the kinds
of bugs that are difficult to debug
those are the ones where your brain is
just a little bit a little bit off and
even doing my best to name things well I
just can't think straight enough to
discern the difference between a suit of
cards and a deck of cards but anyways we
figured it out shorts doesn't silly
describe over 70% of mistakes for me
maybe like 95% of mistakes cryptic says
says oops yeah that was rough I
apologize for those who might have seen
that in advance who are sort of yelling
at their computer screens saying you
have the wrong variable name I apologize
don't really have much much to say that
was just me being silly
anyways that works great so now we can
worry about actually putting things in
the correct order because right now
things are not in the right order if we
if we draw our cards out first of all we
can see that we do get
queen king instead of king queen Jack
ten we queen king jack ace ten nine
eight seven six five four three two one
so we need to actually resource our we
need to re sort our tables right and I
guess I can put it into into U tilde Lua
even though it's pretty specific to this
game so a Rhys or the quads of a card of
a suited table so I'm gonna say function
re sort cards and it's gonna take in a
it's gonna take in a table we're
essentially going to just like
repopulate another table and reassign it
so this should be pretty easy pretty
basic so resore cards takes in the bold
cards right and so I'm gonna say local
new cards gonna be equal to a table and
I'm going to say
well I want to return it so I'm gonna
say return new cards well we'll take
care of the assignment in in our actual
dependencies da lua but it's okay I like
seeing people make little mistakes we
all do it yeah I I don't enjoy doing it
on streem but I've embraced the fact
that it might happen when buying the
cs50 pong I kept getting an eel because
vs code football dot X instead of ball
dot X oh I'm seeing all of your code in
all caps or all of your message in all
caps so I'm guessing there's like a
lowercase vs. uppercase issue in there
but yeah that's um that's an all too
easy mistake to make I think just having
the wrong capitalization for stuff yeah
sorry I'm not reading the actual
physical chat in the chat window I had
it on I accidentally put it on stream a
couple times already and I think some
folks want their message is censored or
whatnot so I'm gonna avoid doing that
but anyways this table we're going to
essentially take the old table of cards
and we know the order that things should
be in right so if I'm looking at my
actual graphics here and I apologize
that we're not like necessarily getting
into the weeds with Psalter itself but
this is kind of a big facet of game
development is you know getting the more
boilerplate e stuff the less exciting
stuff out of the way so and a lot of
this is more lower-level stuff to mess
with graphics primitives and whatnot so
hopefully this is of some educational
value to some people but I apologize if
you're looking to eagerly get into the
solitaire code whilst this is up on
YouTube I'm sure you can skim it forward
or whatnot and this stream is very
likely gonna be two if not three parts
some of which will be next week we might
even be able to do like a Monday Tuesday
thing where both of those days are
allocated to solitaire because I think
we're not going to have a Monday Tuesday
stream but more on that to come and to
be updated on the schedule but we can
see here that we have Queen as number
one King as number two J as number three
so
we can basically say we can work in
order right so I could say here what
we'll do is what we'll make a constant
so we'll make a set of constants for
this as well
so I'll say
pause underscore ace is going to be
equal to and then this is normally what
is this 1 2 3 4 so that's 4 right 4
pause 2 is normally 13 cause 3 is
normally 12 pause 4 is equal to 11 pause
5 is equal to 10 pause 6 is equal to 9
pause 7 is equal to 8 pause 8 is equal
to 7 apologies for how tedious this is
but this is part of the flow pause 9 is
equal to 6
pause 10 is equal to 5 and then pause
Jack is going to be equal to and I can
just actually say positive J pause J is
going to be equal to and I believe this
is actually 3 pause Queen is going to be
equal to 1 and then pause King is gonna
be equal to so this is just an ordering
a mapping of the stuff as I wasn't
before as its laid out in the sprite
sheet
hello Babic isn't Tuesday a code review
stream turns out unfortunately David and
Brian are both unable to make the code
review stream so it's going to be
postponed
and after this stream are going to send
out a message to express as much and
clear all the events off of the calendar
but yes the code review is no longer
gonna be next Tuesday we'll be doing one
probably the next Tuesday and instead to
fill that day what'll probably end up
doing is something like another game or
probably solitaire again if not on
Monday - this might end up actually
being a pretty long series of videos
because this is probably the most
complicated game that we've
yet especially if we do like clicking
and dragging and stuff like that I think
this is gonna be a little bit robust so
expect more solitaire today Monday
Tuesday and code review the next week
and we'll we'll update all the details
on that very shortly and Indra Reddy was
asking we can't reverse the order in the
table there the default table doesn't
necessarily expect a it's based on what
I was just able to read it sorts on like
number values and it doesn't the fact
that we're using objects like the fact
that we're using objects like the card
class which has a nested value and the
reason quads and everything is kind of
sorted into batiks point game specific
for example ace two three four five six
seven eight nine ten Jack Queen King
like we don't necessarily know what the
order differences are between those we
kind of have to do a little bit of
manual work here it's not a very simple
straightforward thing we could map these
all to numerical values and write some
sorting function that does it but at
that point we're spending a lot of time
on engineering we've already spent a
tremendous amount of time on this so I
would like to ideally get beyond it but
the way we're doing it here is still
fairly well designed I think fairly well
fairly clean now what we can do here is
say one by one oh also the careful
Explorer thank you very much for the
follow and did I miss anybody else's
follow I apologize if I did professor
zero zero mr Sirkin as well thank you
very much for the follows let me go back
to here geez okay so here in new cards
what we're going to do or rather in
reefs or cards not Resort not resort
cards or resort cards resort cards we're
going to use this ordering that we just
established here we're sort of ace
rather the first one gets the or rather
new cards actually what we can do is
yeah let's do a set of table inserts so
we'll say table dot insert into new
cards old cards at index pause eh
I think that's how I did it yeah so
we're effectively gonna go through this
now a lot of copy paste but things are
in a bit of a strange order so bear with
me 2 3 4 5 6 7 8 9 10 Jack Queen King
and now if we go back to our
dependencies here I can say G card quads
hearts equals re sort and what did I
call it resource cards and it takes in G
card quads hearts right so we're kind of
doing it to itself and then we'll do the
same thing here for diamonds and then
the same thing here for clubs and then
for spades so now we're getting the sub
table from the sprite sheet so splitting
into four groups and then we're sorting
them and this would look really nice in
a functional syntax where we would have
like sort allocate generate blah blah
blah sort of like a comp series of
functions but in this case we're kind of
doing it in an blocked sequence but now
if I go over to main theoretically these
cards should be in the right order now
and indeed it's same as they are so we
have notice we have ace 2 3 4 5 6 7 8 9
10 Jack Queen and you can't see it it's
off-camera but we do have King as well
yeah pay me now definitely it would be
better to make a good sprite sheet we
are making so much additional actions
just for it to sort our
this is an important lesson though
because you're going to get data like
this online from a lot of if you're
going on open game art or if you're
working with an artist or if you're
desperately trying to hack together
something you're going to get into a
situation where you might not have
everything laid out in the perfect way
right and so the onus is going to be
either on you the programmer or the
artist to do this and if your artist is
unavailable No then you're gonna have to
kind of figure out how to do this in
code so ultimately you should probably
figure out how to look at quads and how
they work and how to sort the
information and also how to use data
structures like tables dictionaries hash
tables to a to make this work
virtuoso seven I'm still trying to wrap
my head around reading a spreadsheet so
sure so the spritesheet is essentially
just the do I saw this running woops
no why that's still running occasionally
a little crash like that but
occasionally you'll run into an issue so
I what was it well I just got
sidetracked no sorry
different train of thought this is what
a sprite sheet is it's essentially all
of your textual texture informations are
not textual information texture
information for your game and the goal
of a sprite sheet is to make it so that
you don't have to have separate textures
for everything in order to read the
textures it's different depending on
which framework you're using but what
you effectively need to do is split up
your game your all of your sprites into
rectangles you need to say I want a
rectangle that defines what the Queen
card is or what the King cart is you
know you effectively overlay a grid on
top of this entire thing and that's what
we did in our util da lua here up in the
generate quads function so what this
function does is it creates a new empty
table and to create an ins we're going
to populate it with what are called
quads rectangles effectively and we pass
in what we want the texture width and
the texture height to be for each quad
and this should probably actually be
called quad height and quad
with which I can do just like this Oh
actually in this case they didn't
actually do that I don't think I
hard-coded it but in any case what you
want to do is you want to iterate over
your spreadsheet and what we did is we
did it vertically instead of
horizontally but you say starting at y 0
I want to go down for every card so I
want to start y 0 create a rectangle
that's the width and height of the card
save it in my table go down at Y level
you know what the next card height is so
add the card height to Y so now we're
actually here
create a rectangle down to this corner
ok go down to here create a rectangle go
down to here create a rectangle and when
we get to the bottom I want to say okay
now we're gonna start back at the top
but I'm gonna shift X over I want to
make X equal to card width I'm going to
the same process when I create
rectangles all the way going down shift
over go all the way down shift over
shift over shift over going all the way
down each time creating a rectangle each
time adding it to my table and so now we
have a flat table of all the quads in
our sprite sheet right so now instead of
having to draw the entire sprite G we
can draw just an individual card the
problem that I ran into was that our
data is a little bit weird right we have
a queen here we have a king here
normally should be king queen we have
our ace after the Jack ace should be at
the end it shouldn't be after Jack so we
need to resore Terry thing too and we
need to divide things up ideally by suit
so that we can index into the right suit
at the right time right and so this this
stream is ultimately more of a lesson on
how to actually sort card data and make
a card a deck class than anything else
that functions well in the context of I
think any card game any casino card game
because you could use this deck class
that we're creating now for probably
anything poker blackjack you could spawn
multiple decks add them together you
could do all kinds of different things
but in this case we're using it just for
solitaire but the fact that our data was
in a less than ideal format means that
we
to kind of go through a few extra hoops
we have to jump through some extra stuff
in order to you know get the aesthetic
that we want and this is not all not too
uncommon for example in my game
development course we actually ended up
using another pack by Kenny for mario
kenny platformer or i think it should be
called well it's up here and this pack
is insane
it's a beautiful pack with a ton of
amazing artwork not pulling up here I
actually have it I think locally here on
my hard drive on this account because
they use the same account to teach the
game dev course but you know a dime at
least in the chat has been paying
attention to and the Jason G says hello
: what's up hello Jason good to see you
again
I remember Jason G G for grease I'm
guessing if I remember correctly in the
in my J Harvard account if I go to dev &
Mario I think it was right here um was
it Mario thought it was Mario right
anyways graphics if we look for example
at well so these are backgrounds and so
the backgrounds in this case you would
need to determine their size right this
is another example of where you would
use quads three rectangles one for each
of these backgrounds figure out how high
the rectangle is so start at 0 on the Y
right up here and create a rectangle
that goes this wide this tall shift down
here make another rectangle that's this
wide this tall shift down here into the
same thing but we got data from this as
you can see I'm scrolling through these
sprite sheets these all all have
different dimensions different textures
in this case you have doors that are
twice as wide as the other ones if we
get to the really fun stuff and Adam
actually probably recently just saw most
of this let's look at this one for
example this is crazy this is a crazy
sprite sheet and I loved it but look at
how much effort goes into parsing a
sprite sheet of this complexity right so
you can massage the data all you want to
but as complex as your thing
you're gonna eventually need to find
ways to programmatically do a lot I
ended up splitting this whole section
out for the class so that because these
are all consistent these all have
consistent values but notice that
they're all sorted on color right so I
still have to do some processing of my
tables to say I want to chop all of my
metal or I guess these are snow tiles
out into one table I want all my grass
tiles out into another table I want all
my sandstone tiles out to another table
I want all my terrain ones separate from
the title toppings out to other tables
so yeah it gets complicated but it's a
valuable lesson I think also that this
kind of stuff will take time and it is
essential in game development for very
complex games games like terraria which
have thousands and thousands of sprites
just imagine what goes on in terms of
them parsing their information and we
are just parsing a deck of cards like it
gets exponentially more difficult than
what we're doing today but there are
ways that you the programmer if you're
willing to put in the time and energy
can make this easier for yourself and
certainly reordering things
restructuring things it's a trade-off
you have to say do I want to spend my
time doing artwork or don't want to
spend my time doing code and as a
developer you might not have the finesse
the the the sort of finesse with things
like Photoshop or a sprite to do this
manually and you might not have an
artist that you can rely on so an
important thing to take into
consideration when you're getting into
doing sprite based game development
separately though I do apologize for how
long it has taken I didn't mean for
particularly the bug that came up
earlier that was a very elusive bug but
everything is now in the right structure
so this is great actually very happy we
have everything rendering correctly we
have all of our sprites as you can see
in the right order
even though King is sort of cut off we
can assume it's rendering correctly
let's go ahead now and actually go into
my card class actually now this should
just work so now a value of 1 is an ace
the value of 2 is a 2 so now I can just
index into into the right suit
and into the right value right in this
case not value and actually this needs
to be self does suit and self dot sorry
and self dot face so someone's question
earlier were we still using value of her
face we actually were in that particular
context virtuoso seven I've got to dig
into Lua and love ya know definitely and
I hope that that example I was just
trying to illustrate helped a little bit
conceptually at least but look up the
documentation on quads for example which
we had up here look up the different
look up graphics the graphics name space
right here love graphics write a simple
program that splices up a simple texture
into multiple quads you know figure out
where you're aligning them figure out
where things are cut off or maybe
they're too big or too small get your
hands dirty that way and then work your
way up to automating the generation of
quads like we just did which we
effectively just made a script that just
looped over an entire set of set of
rectangles and you'll develop that
comfort over time but certainly if
you're not used to it and if you're
looking at this sort of automated
approach this a programmatic approach it
can be a little overwhelming so I
totally understand now that we have the
card quads table here in the right order
everything is laid out correctly we can
reference the suit and the face and draw
it at the XY that we care about so now
if I go over to main let's test this
card class make sure this is working I'm
going to create a card here and I'm
going to call this a Queen of Hearts and
the Queen is going to be given the value
Queen whoops sorry Hearts Queen and
actually I'm realizing that I think in
terms of the the face and then the suit
so I course sort of think of the fact
that we should have our card constructor
take the same sort of thing and actually
this should be card not Queen of Hearts
so what I want this to look like is
Queen of Hearts like that right that
looks nice
this
this looks very it's obvious what I'm
trying to do with this code so what I'm
gonna do is in my constants file I
should probably say queen is equal to
let's say let's start let's start from
from the beginning let's say ace is
equal to 1 2 is equal to 2 3 so you know
bear with me here we're just making
constants to make our code more readable
that's the whole goal of this 6 is equal
to 6 seven 7 eight 8 nine see what's at
9 10 10 Jack is equal to 11 Queen is
equal to 12 and King is equal to 13 so
now this is all great and actually I
could replace all of the no these are
positions those are different so this is
great although
well I was gonna make these refer to
this but that's may be overkill at this
point we don't worry about that too much
but now I can say oh also the suits you
want this the suits as well so let's say
let's say hearts wait how do we order it
before it was it doesn't really matter
actually
so hearts hearts diamonds equal to
diamonds clubs is equal to clubs and
spades is equal to spades and also thank
you to apologize need to keep this up PK
1 for the follow as well okay cool so we
have constants defined let's comment
these out so these gonna be all of our
suits these are going to be our faces
these are going to be default positions
for faces in the spritesheet starting
indices for suits in spritesheet
and then these ones are all pretty
self-explanatory okay so this is good
okay so main now we can say we can say
something like this this this looks
great we have the constants defined such
that we can do something like this right
so I could actually say Queen of Hearts
I'm gonna make this local so that it's
not accessible from within my other
modules this is something you want to
take into consideration time now P me
now I apologize mispronouncing your name
you don't care about memory allocations
right in this case no love 2d manages
all of the memory allocated for you
underneath the hood so you need to worry
about it at all the thing that you would
need to worry about is if you had a ton
of resources and you're allocating
sprite texture data because it's managed
for you you don't necessarily know how
much is being allocated but it's safe to
assume that if you have a symbol
allocated to a texture of data it's
going to be in mem
somewhere and if you have a ton of
sprite sheets that are all pretty large
especially things like modern games have
many gigabytes worth of large textures
you can run into memory issues so you
want to find ways to avoid doing that
either by loading them and deallocating
them dynamically or avoiding having as
big of those textures in your game right
because you'll necessarily need them
depending on if you can compress them in
the right way
fall back to zero thank you very much
for the follow so let me be aware of in
this case we are dealing with a very
small texture this texture is how big is
this texture it is 71 kilobytes so
miniscule and there we're just loading
literally this texture all the quads
aren't loading the texture at all the
texture itself whenever we call loved
our graphics draw that's being
referenced and the quad is just kind of
telling draw which window to draw that
same one texture but there's only one
copy of the texture in memory which is
really nice so quads are very memory
efficient and that this is why another
reason why it's more important to have
the I think the sprite sheet then it is
to necessarily have every individual
sprite image you save bits right because
you can get your image compressed in a
way such that the whole image is smaller
than all of the separate images together
you can have it such that your graphics
card doesn't need to load different
images into memory it's just you get a
lot of savings that way so good question
up now if I do and here instead of
drawing the card specifically if I say
also Garrett of whoops you know no
longer print this we can say
queen-of-hearts render at 0-0 and I
don't even need this actually I'm just
gonna say queen-of-hearts render at 0-0
so now we're calling just the render
from our card class so we're deferring
all the drawing logic to that class
itself which you've already wrote in
here we can see that we have it's
referencing the gee card quads table at
the suit and the face that it has and we
passed in the hearts and the
face in the suit which is actually in
the right order right now so this is
perfect so now if I run main.lua we
haven't we haven't loaded a card into
dependencies yet so let's do that so
require source slash card and then I'm
gonna do deck as well and do I care
about constants being first I think I do
sometimes they'll run into an issue if
for example card was using constants or
some of my other modules we're using a
constant you want you sort of want
constants to be first before all of your
actual modules just in case because it
does read it top to bottom and it will
go it does a depth-first sort of search
on every module so it will load all the
symbols from one and then go to the next
one then go to the next one so you want
to avoid having references to constants
before constants has even been loaded
into memory right let's go ahead and run
this and lo and behold we do indeed have
a queen-of-hearts rendering to the
screen in the way that we wanted it to
be rendering which is super cool right
this is this works great now the next
thing that we want to probably check for
is clicking and dragging cars and we
haven't actually done this before and I
haven't necessarily thought too hard on
how we would implement doing this but I
think just a simple flag saying whether
the card is being picked up or not
should work fine and then we can end up
considering whether cards might have
children later on and this is important
because if we if you are familiar with
solitaire in the actual game you can
pick up any revealed cards an entire
stack of revealed cards and when you do
that it will pick up all the cards that
are on top of it so you can pick up an
entire stack rather than in one
individual card at a time and this is
why I think this stream is gonna be
several parts because there are actually
a lot of pieces involved in solitaire
which is great because I think making
something fully fleshed out like this
could be fun and a good exercise and a
good codebase to have on line later
but just as a forewarning this might be
a rather large project now I realize we
actually haven't made a git repository
for this yet so I'm gonna do that I'm
actually gonna get in it get at
everything
give commits initial commit with cards
rendering I'm going to I got my DF store
in there we just talked to Babic not
yesterday about having dot files or
something or someone else having dot
files in their repo so I should do my
due diligence and probably not have one
of those in my repo if we're gonna do
this right which I want to do hate how
condense this is doing everything at
720p makes it a little bit tricky to
mess with some of this stuff but if I do
Star Dodds I might need a back slash dot
or I can just do dot d s door like that
and that should work too and now if I do
get commits rather get RM dia a store
get and get commit removed yes store and
now what I need to do is go to github
actually create a repo for it so if
you're not familiar with github get up
comm lets you host source code for other
people to collaborate with you on and
they can give you pull weather called
pull requests it looks like I have one
right here oh this is for the course
that I'm teaching if I create a new
repository get up is a little bit slow
sometimes it's a pretty massive website
we're gonna call this solitaire stream
like that solitaire implemented on
stream twitch.tv/eds btv public and then
quick repo going to copy this URL going
to get remote add origin that get push
up stream origin master and now if you
go to that URL which I will
post in the chat here just there oh
Babic saying that was you with the get
ignore yeah if we're going to if we're
gonna critique you on it we have to do
our due diligence as well so I am very
happy to make sure we're doing the right
thing
alright Babic saying we will need one
more sprite for the back of the cards
correct we will need that absolutely the
beautiful thing about this that this is
actually very easy to do because we just
need to import one sprite and and we're
not using any quads on it we're just
using a regular texture so I'm going to
go back to my folder that had that or I
saw that folder open no I don't that's
okay let's go over to some streams
solitaire and graphics shoot it's not in
here it's in downloads I think is it
board game pack yep in here and I'm
going to go ahead and go to cars choose
a backing let's get a vote on stream do
we want blue green or red and which
design do we want the the small sort of
simple design the large pattern design
or the flat design actually plain dark
background multi design line rectangle
design line rectangle with multi pattern
or a lion rectangle with minimal pattern
I personally like the the four symbols
like this I don't know if I care too
much about the line or not I guess
that's the only one that has the line so
or the only one that has the four
symbols so my vote is for the small this
small grouping but I'm color agnostic so
whatever color folks enjoy in the chat
I'm good for blue blue three blue three
is this okay blue three we have blue
multi green minimal blue five okay so
it's looking like people like blue the
most Oh No maybe not we got a lot of
greens look
we're tired blue and green I should have
a pole I should have like a polling
widget on here or something green 5 I'm
getting a lot for green 5 I uh
Green fires nice green five green five
green five green minimal I'm guessing
this what people are saying is green
five okay red team blue five any green
five okay we got a lot of green fives
we're gonna go green five i apologies
apologize that that's not the car that
you wanted we had overwhelming consensus
it seemed like for green five so i'm
going to go ahead and paste that right
into there we're gonna call this card
back like that actually to keep it
consistent with the other thing for
playing cars I'm just going to camelcase
it so card back PNG we have to shrink it
remember we shrunk all of the other
cards so what I'm gonna do is I'm going
to open this with a sprite I'm gonna do
a very super simple sprite size divided
by two so make that 70 by 95 do that
save it done boom and if I go over to
here if we're gonna do we're going to
test that this exists right now that
this works well so if self dot hidden
then else
and what we can do is say loved up
graphics draw G textures card back at X
Y and we have to actually add that to
our textures thing here so I can say
card back gets equal to love dog
graphics new image graphics card back
dot PNG run that so self dot hidden is
false but if I change it to true as by
doing this we do indeed see we have a
back ground on the card super nice there
it is beautiful code an options menu for
the card color that sounds a little bit
ambitious cryptic sir said I apologize
mapping and I think green is Master Yoda
I'm not David though so I mean to be
fair if David were in the chat or if you
were here programming this I think
that'd be the perfect color for him
we're getting a lot of looks like window
light today this is interesting I
haven't seen it this bright in here
before sweet so we have cards we have
card backings it's taking us a while to
get there granted but we've done quite a
bit we've done we written quite a few
functions we have quite a robust set of
things here everything is completely
from scratch except for the dump to be
fair we got the dump function off of
Stack Overflow but you know we won't
worry too much about that let's go ahead
now and think about clicking and
dragging the cards around because this
is important if we want to do anything
in this game it pretty much relies on us
clicking and moving cards around be it
from the tableaus to the four piles or
from one tableau to another tableau or
from the stock to a tableau we're going
to need to have this functionality we're
going to be able to click and drag our
cards around so it makes sense that the
card should be able to check for the
mouse input itself and the first thing
we want to do actually and we'll worry
about deck at some
in your future but I'm going to say
Queen of Hearts
update in Delta time and I'm going to
say we're going to create a new flag on
the card we're gonna say self dot picked
up and we're going to set that to false
now if we get the card clicked on so if
love Mouse dot button pressed one and we
actually need to implement this
ourselves it's still doing the indent oh
because I'm not typing then that's why
okay
whoops hopefully that wasn't me just
let's just retype this again if love dot
Mouse that button pressed one then it's
still doing it what is going on okay
that is that is exome so let's go ahead
and write this function that we need to
actually get mouse input detected from
within functions outside of main
so normally main gives you the ability
to say function load Mouse pressed
button right just like that and I think
it actually technically gives you an x
and a y as well I'm not 100% sure but we
can easily look at the wiki and say
loved mouse and love that Mouse pressed
right here oh yeah XY button is touch
and presses so had the order wrong so XY
button we won't worry about is touch or
presses presses would be good though if
we had the notion of a double click
which is common in solitaire to double
click your cards up into the four stocks
or the four sorry sections where you
sort of build up your full suits right
but we're not gonna worry about that
we're probably just in use left and
right click for this for ease ease of
use right click will be reallocate left
click will be in other interactions a
kind of thing cryptic saying might be s
code does that as well yeah I'm not sure
it hasn't done this before so it's it's
something new
somewhere that's been funky but normally
you're given the ability to say loved-up
mousepressed within main.lua because
that's where love the love to D is
looking to see where all of the mouse
interactions are taking place but we
want this to be accessible from within
the card class and it doesn't actually
give you the ability to override these
functions within your car class so again
instead say well rather it does give you
the ability to override them within your
card class but if you have multiple
definitions for them it'll cause issues
you'll have we'd have to over write this
in every module that we wanted to
override the mouse press behavior which
would cause a lot of bugs it would be
bad so we want some way to sort of
globally make a table of inputs that
have registered on that frame and check
to see whether the mouse has been
pressed a single press set frame and we
can easily do this oh it looks like
night Chris Oh interesting I didn't
realize that that's fascinating
the night Chris s kindly plugged a link
to an issue for vs code where Lua
formatting has been bugged and I
recently did just update Lua our update
vs code so that makes total sense that's
disappointing but you know it's a big
project
things are gonna slip through I guess so
what I can do here if you want to make
this globally accessible we can do is
say in my love that load up first gonna
say love mouse keys or buttons pressed
equals an empty table this love Mouse
that buttons pressed this is something
we're creating this doesn't exist but we
can tap into the love Mouse name space
because Lua is a dynamic language and I
can override it with whatever I want I
can say love Mouse dot Colton equals
some value and it will work in this case
love that Mouse that buttons pressed I'm
just creating an empty table here this
will be accessible anywhere in our
application I can make this a global
table too doesn't matter you can make
this something called global button
table and assign it to it but this is a
little bit easier to sort of keep track
of and reason about and then love that
mousepressed
this will fire every time we press a
mouse button any time so I can say
is love Mouse that buttons pressed at
button it's gonna be equal to true so
what this just means is as soon as we
press a button that table will update
and have a true placed or at whatever
button
we ended up pressing only on that frame
and the reason it's gonna work is
because at the end of update which
remember fires every frame I can say
love mouse buttons pressed equals and
empty table so refresh from the table
every frame so erasing whatever we did
flag on the last frame so it'll only
tell us true for the things that did
fire this particular frame and what we
want to do to make this accessible is
say love mouse dot what did I name it I
called it buttons pressed oh sorry
was button pressed this is typically how
I named it I got it confused over here
so I can say if loved was button pressed
one now one is by default your left
click to be your right click and then if
you have a mouse with a bunch of other
buttons those will get assigned
incremental values so you could you
could theoretically bind love to work
with very robust modern mice for gaming
and those sorts of purposes so love that
Mouse boys button pressed and then I'm
going to look for a particular button
and then I can just return whatever is
at love Mouse dot buttons pressed at
that button and if we're testing on this
frame and I clicked left click and one
is set to true and I'm checking for one
then well I can very easily ascertain
that I clicked on this frame no matter
where I am in my application whether I'm
in a class a separate class or even with
if I'm within main dalawa and that this
gives me a lot of versatility with
checking for input across my entire game
so if love dot Mouse stop was button
pressed one then I can say self dot
picked up is equal to true and then if I
say if self dot picked up
than
what I'm realizing now is these need to
have an x and a y so self dot X is equal
to I guess we'll be see a bit we value
it's up to act self dot y and then we'll
say self dot X self dot Y is equal to
love Mouse get to get position which
should return an x and a y oh man that's
fun
I even I even right now tried to
preemptively not do the end and just
keep this indented and then press ENTER
and type N and it still went to the
beginning of the line so it is
completely messed up anyway
we can deal with that don't update your
vs code if you if you're using PS code
and you're doing Louis stuff apparently
cool so now what this is gonna do this
is using double variable assignment
unpacking so love that Mouse that gap
position actually returns two variables
so I can assign to variables to the
return of this self dot X and the self
dot Y because it returns an X Y couple
which is nice and this actually needs to
get an x and a y now which is ok we can
deal with that back up here I'm going to
say this gets 0 and 0 and now what I
just did here was actually instead of
setting it to true I set it to the
opposite of whatever whatever it
currently is so self dot picked up
equals not self dot picked up means that
if it was false its true and if it was
true it's false so this allows us to
toggle that state which means we can set
and put down our card where ever we want
to so let's go ahead and do that boom
doesn't work which is okay why doesn't
it work card that update are we updating
let's make sure oh you know why because
we're drawing at X why not self dot X
and self-taught way let's do that
those are global variables that didn't
mean anything we want those to be the
field variable the member variables of
this card object right so let's try that
again
we do indeed have now the ability to
click and drag a card around and it gets
kind of locked to the bottom of the
window too which is cool
and if I click again I can set it down
so I can set cards down wherever I want
to now it's a little bit funky and that
I click on it and it kind of jumps to
the top to right at the top left corner
of the card and that's not really the
behavior that I want I kind of would
like it to Center if anything so what
I'll do is I'll say self dot X Delta Y
is equal to love that Mouse get position
and then I'll say self dot X is equal to
self dot X minus rather hmm yeah well
we'll do that that's fine self dot X is
equal to self dot X minus card width
divided by two and self thought Y is
equal to self dot Y minus card height
divided by two now this will Center the
card on the mouse which is better
behavior certainly right it still jumps
a little bit but it looks a lot better
than having it be at the sort of top
left of the card we could calculate an
offset so I could I could when I click
on them on the card I could figure out
where I am relative to its X Y and then
that would probably work but oh you know
what I'm doing - I'm actually not even
checking for the bounds of the card so
accurate so actually I just realized
this I click here and still pick it up
so we actually do need to check to see
whether we're in side the card so to
speak before we pick it up so why don't
we do that dizzy devil is saying this
language has so many cool things built
into it I do like
I do like Lua yeah it's pretty nice sent
to the middle of cars is Bhavik yet we
did we leave it as a toggle click rather
than click and hold yeah probably leave
it as a toggle I think it's kind of
annoying to click and hold especially on
a trackpad which I've what I'm actually
using right here so I think I think
that's a better design decision honestly
it's a little easier just click it move
it around click again to set it down
that makes sense to me
let's go ahead actually and if we click
on one we don't want to just set self
that picked up to equal to not self top
picked up I want to check to see if it's
in the bounds of the card so I can say
local X Y is equal to love dot Mouse get
position and then I can just say if X is
less than or equal to self dot X and X
is greater than up sorry greater than or
equal to sell X and X is less than or
equal to self that X plus self dot width
and Y is greater than equal to self dot
Y and Y is less than or equal to self
dot y plus self dot I just realized self
dot with isn't the thing so I'll do card
width and card height then the annoying
indentation bug and here is where we can
actually say self dot picked up is not
self dot picked up so now we're actually
verifying the constraints we're saying
making sure that the XY of our mouse is
within the boundaries of the card and
this will help us to make sure that
we're in the correct spot so if I click
I can click out here all I want but as
soon as I click on the card now I get
access to it and I can click again so
well everything is great perfect
fix that bug everything is beautiful now
what we can do we have about another
maybe thirty to forty minutes of time I
think before we
maybe wrap up for at least this part 1
this part 1 isn't a terribly robust look
at solitaire itself but more how to
create a deck of carbaryl cards how to
mess with them we should set the game
board up at least so that we things sort
of look like solitaire so what I'm gonna
do is I am going to in main what I
probably want to do actually is have
something like a game board class a new
file game board Lua and game board is
equal to class function game board and
NIT and this is basically going to draw
the entire width of our screen and one
other thing I should do is set our
screen to 1280 by 720 p so we can do
love dot window dot set mode to window
with a window height and let's make
those constants so window width all make
those are the very top of our file here
so window width is equal to 1280 window
height is equal to 720 I rerun this we
do indeed have a 720p window which is
great everything is great as we saying
so glad there'll be a part two I forgot
to mention that as Li is to thank for
this stream actually and this series of
streams she recommended solitaire to us
so shot us to Ashley for the
recommendation it's a great game it's
gonna be fairly complicated especially
relative to all the other games that
we've done on stream but we've done so
many fairly simple games that I think it
feels appropriate to start diving into a
little bit deeper territory and that's
the plan I think going forward to will
be doing more games that are in a more
complicated sort of domain solitaire is
not super complicated but it's you know
reasonably complex relative is something
like you know the typing game hangman
things that we've done in the past this
one has a lot of bits and pieces and
especially when we get to things like
child Accardo that you pick up a whole
pile depending on where you click that's
going to
somewhat relatively complex so it's
gonna be fun but you know stick with it
it'll be a few parts probably this first
part is mostly just getting the card
code bootstrap so cool everything's
caught up on the on the chat there I'm
gonna go ahead now and we have our
window all set up I'm going to define
the game board the first thing that I'm
probably going to do is say I probably
wanna do the drawing and also dirty
dazzle thank you very much for the
follow I'm going to say game board
render and the get this is going to do
love graphics clear and I want to choose
kind of a casino II color I think
probably something like this this is a
nice little dark green actually
so we'll do something like that so I'll
say is 0 and I'm using a relatively new
version of Lua of love so the numbers
are floating points between 0 and ones
I'm going to say is 0.8 0 and 1 and that
should give us at least a nice green
color for the board and let me go ahead
and in main actually in dependencies we
should probably require it first I'm
gonna say source game board just like
that I'm gonna run it sorry not gonna
run it have an instantiate it yet and
main dot Lowa
I'm gonna say a local game board equals
game aboard down here I'm gonna render
the game board before we actually
rendered the Queen of Hearts card and
then I'm gonna run the code and that's -
that is way too bright so we're gonna
lower that brightness down down to like
point 4 let's try that there you go
that's not bad right it is a little
classy with the green cards that we
chose but let's let's bring it down to
point 3 let's see how that is yeah
that's not bad right and now I can click
and drag this card around and everything
is kind of you know we're getting
incrementally closer to what we
eventually want our game to look like
right so let's look at the board let's
look at the Saltaire board at its start
and see what we're dealing with so we
can see that we have a few
things going on here number one for the
diagram we have our four slots for where
our finished card piles are going to go
we're gonna have four card piles we
build up from Ace to King and basically
you can just and they're all student by
the way so this is diamonds hearts Club
spades for example they all have to be
that specific suit and they have to go
in order so we're gonna want those
minimally so why don't we start laying
laying these out a little bit we can do
this fairly easily I can say love
graphics to draw a rectangle rather and
we know that these are going to be the
size of the card so our card size is 70
by 95 so let's decide you know we want
it to be maybe mmm what make sense let's
do it at and we can by the way
eventually come back to this and make it
fit the screen nicely and maybe zoom in
a little bit with push make it look
little bit more pixelated look a little
bit cleaner crispier but loved our
graphic start rectangle I'm gonna draw
some rounded rectangles I basically want
to do what I'm doing in what we're
seeing in this picture right here which
is for rounded white rectangles so to do
that all I have to do is say we'll say
main stack placeholders we'll start
drawing them kind of in the left ish
area so I'll say I'm gonna start it
we'll make this a line rect first of all
I'm gonna say start it
10 on the Y and we're going to draw the
rectangle at card width card height and
whoops sorry 10 and then maybe 50 on the
Y and these are magic numbers we can
worry about this in a little bit and the
important thing that I want to do also
is round it with this rounding factor at
the end which kind of functions similar
to CSS I forget the exact thing that you
can do I think it's border-radius and
then you're you end up actually shaping
rectangles into circles which is pretty
cool so we're just gonna do that there
just like that and now if I draw that
and I remember the game notice that we
do indeed have sort of a rounded place
to put our first card which isn't going
to stick to it it doesn't matter it's
not there's no logic for our card to
actually stick anywhere but we're laying
out our board so that later on we can
end up granting functionality to these
locations which we will do so let's do
that for all four of them I'm going to
say this one will be at 90 this one will
be at a hundred and seventy and this
will be at 250 right so now we do have
four of those slots just set up in the
way that we wanted them before okay cool
now what we want to do there's more more
things that we want to take care of this
number two and this number three and the
number two in the number three are
actually related there are certain
versions of solitaire where you draw
three cards at a time instead of just
one to act as your next card that you
can place down amongst your tableaus we
are going to just do single card draw
look like it's done in most digital
forms of solitaire at least most of the
versions that I've seen and so we're
going to sort of just right we're gonna
put a placeholder down and then maybe a
card to illustrate that whoops didn't
mean to do that
so we'll make this be the active stock
card and I'm just going to draw this
I'm gonna draw this a bit more to the
right so I'm gonna make this maybe 400
that's our active stock card so that
works great and then beside that I want
the stock itself right so we'll say this
will be at 480 just like that and then
lastly we want all of our tableaus which
is one two three four five six seven of
these which they're directly below our
other cards so and I don't know if this
is the technical term for the whole
stack I know it from what I've read
yesterday the tableaus are the cards
that are on top of the stacks whether
they're and they refer more to the ones
that are revealed folks that are more
familiar with solitaire I might be able
to correct me on that we're going to
make seven of these and actually they
need to map up to the ones before them
so I might need to do a little bit of
editing of the active stock and the
regular stock but we need three more and
they're just gonna we're just gonna add
80 to them this is going to be 3:30
this is going to be 4/10 and this is
going to be 490 just like that oh and
then also the tableaus need to be
shifted down by at least 95 so 110 so
these are all gonna be at 160 so we'll
do that 160 just like that and notice
that the cards up above are slightly
offset so we can do is say 410 and 490
just like that and now we have an even
align to grid of what we will end up
using for solitaire so this is great
this looks pretty nice things are moving
along and we can again move our card
which is great and set it down wherever
we want to this isn't terribly useful
yet because there's no logic we're just
moving in a sprite around on the screen
now to sort of simulate what things will
look like we can lay things out sort of
in a Pho manner I guess so the game
board is also going to have and it is
- its grid spaces it's gonna have active
cards so I can say self dot and we'll
end up probably doing is self dot
tableaus it's going to be equal to just
an empty table well it's gonna have a
table of varying cards here and what
we'll do is we'll say I'll actually
generate the well it will generate this
so we'll create an empty table and then
I'm gonna create a function called
generate tableaus and the important
thing too is that we need a deck and so
the deck should probably be visible from
outside of the game board should it
eventually the ideal way that we want to
structure this is in a state machine and
we can do that on the next stream
because we only have about 15 minutes
left so we'll worry about all of the
those engineering concerns the state
machine and the game states the various
game states when we and it really
there's only one main game say it would
just play state and then you get a game
over and then can toggle back to the
beginning again which is pretty easy so
don't worry about that too much now we
could make everything theoretically
accessible from the game board class and
sort of have that be the container for
everything do I care about that hmm I
guess it makes sense yeah we'll do that
so in that case it's gonna have a deck
and the deck is gonna be instantiated
like that
and generating tableaus is going to end
up basically going through our deck
drawing random cards populating
everything and setting the rest of it in
the stock which we saw earlier so
basically going through these piles here
flipping a random card two random cards
three four five six seven random cards
put the rest here and then we draw one
card at a time from the deck and reveal
it and it gets put into the stock here
right and we get to manipulate it so we
keep this into consideration this is
pretty easy I think having everything
here in the game board I think this
makes sense so and this is all okay here
and actually what we can do I can put
all of this in its own function and call
self draw back ground and the reason
this is sort of compelling is because
all of this code is essentially just the
background color and the grid outlines
and we can just chunk it out into one
thing we will be drawing all of the
cards at some point within the game
board as well sort of so we don't really
need to conflate multiple things in one
area we can function it all out and just
call the functions as we need to makes a
little bit more readable more
maintainable cool let's worry about the
deck because we haven't actually done
anything with the deck it's an empty
class so what we should do is make sure
that it generates all 52 cards
which it will and then randomizes them
so we will flatten all 52 cards
so we'll say self.cards is gonna be
equal to an empty table and then through
each suit which we put in our which we
had in our bub of dependencies down here
hearts diamonds clubs and spades we have
the G card quads actually no we don't
even need to do that what am I thinking
no we can this is fine no we this would
be easy so we say four eyes equal to
well actually no it doesn't work we
can't iterate over the club well just
say four oh I can we can do this for I
gets one two cards in suit not in deck
in suit don't make this mistake it's a
minor thing the mouse pointer set to the
center is blocking the hidden card
design oh yeah a little bit that's okay
we don't really care about it right now
we carefully because we're gonna see a
bunch of cards sort of laid out all
together at some point so that's fine
it's okay
four eyes one for the number of cards
and suit do now can also I remember when
you can indent here and it would
actually take you inside the loop now it
just takes you to the left edge so it is
really messed up we'll say table dot
insert self Dot cards 52 over 13 says
fulfilled gaming you're gonna do that
cool card flippy thing when you win
cryptic s-- I am NOT I've seen a couple
of things like that I'm not 100% sure
what you mean and RI FBR says could use
a while loop instead you could use a
while loop anywhere you can use a for
loop I generally think better in this
problem for as it using a for loop so
don't
while up is necessarily useful I think I
want while loot more when you don't know
when something is going to terminate if
you know when something is going to
terminate I feel like you're at a bigger
advantage letting a for-loop maintain
the flow of the loop rather than using a
while loop I feel like it's just safer
and generally easier to reason about
than a while loop while it was good for
something like user input or something
like that
you know when you don't necessarily know
when something is going to end up
completing so we're going to insert a
new card in our deck for one in every
card in suit and we're actually gonna do
four of these and we're just going to
insert a I card of Hearts I of diamonds
I have clubs and I've spades and so now
what this is gonna do is it's not random
at all this is putting all of our cards
as a flat list of 52 cards which are all
sort of in order of every face card but
all four suits so it's going to give me
all four aces all fours twos all four
threes all four fours in order all until
all the kings using this particular loop
so once this is all done we do want to
shuffle the cards
and function shuffle there was a pretty
nice algorithm for doing this it's been
a while since I've seen this fishery
Yates shuffle yeah I think that's what
it is right
puts all the elements into a hat it
continually determines the next element
by randomly drawing an element from the
hat until no elements remain oh I see
okay so we could do something like that
yeah
so what we could do is say essentially
for what we would do is say local what
do we want to copy all of these put them
into a hat we could do random but then
that doesn't end up you end up in a
weird case where you have a very sparse
deck and so your algorithm is very
inefficient it's better to take the
element from this from the base table oh
we could do that
yeah we could do that we could say local
local base table base cards is gonna be
equal to self dot cards right so we have
a reference to self dot cards and then
we're going to say local new cards it's
gonna be an empty table we're going to
assign self dot cards to new cards so
eventually the data that was being held
by self dot cards before is gonna be
memory collected garbage collect it's
gonna be gone right so what we can do is
say four eyes equal two cards in suit
until one do another thing we're gonna
need to do if we're gonna use
randomization what we should probably do
is say math random seed OS dot time if
you're unfamiliar with this basically
this is seating our random number
generator with the time the current time
in milliseconds since 1970 which is
always going to give us a very big
number and this big number influences
our random number generator new shuffle
is nice as well I'm not sure for this
purpose but I've used it somewhere in
algorithms course gotcha this the this
ducks list is what are you doing yet
we're making solitaire we're not quite
doing super super ton of solitaire but
yeah it's gonna be we're making progress
we've effectively just have our board in
a random deck of cards and the ability
to click and drag cards around and a not
really a whole ton of game logic yet
just given the complexity in getting a
deck of cards working well and
organizing it sorting it by suit and
value and in this case getting a shuffle
setup this is a this is kind of a lot of
the thing you have to do with a lot of
casino style games is just making sure
your card system is working
if using chips or some other type of
system it's the same deal what we're
gonna do is
I can say table dot insert into new
cards base cards at math dot random at
the length of base cards right so this
is cool this is effectively putting a a
new card or rather inserting a new card
into our new cards getting a random
index into our base table of cards but
we can do this in a nice clean
algorithmic not super random way where
we're looking at sparse entries and sort
of crossing our fingers we get
everything done if we say base cards at
index I is equal to nil because if you
set something to nil in a table it'll
actually bring up the Tate of the or
actually I think we need to do table
that remove base cards you can do nil as
well but I think these will function
identically table remove base cards at I
hope not I at this is yeah we need a
local random index equal to this so we
can use it afterwards so we can actually
clean up our table let me verify that
that's true I believe that that's true
table remove in a Lua
yeah sing give it an index cool and I
believe my default table don't remove
will actually remove the last index in
the table is that true
yeah last element of the array if you
don't specify an index table that remove
will work that way in this case we're
specifying that we want to remove that
random index that we plucked off and so
what that's going to end up resulting in
is that this method
andum given this the length of base
cards will actually be one smaller and
so it won't actually try to index
outside of the array because the table
is actually gonna fit back in to fill
that space so this is nice this is super
convenient and at the end of this we're
going to have this new cards it's all
the shuffle cards of a previous deck and
it's gonna get reassigned to self dot
cards so the prior data structure is
gonna be forgotten effectively now if we
test this let me actually render this a
little bit so I'm gonna say deck render
I'm just gonna render the first five
cards just that we can verify it that
it's rendering appropriately I'm gonna
say for I is equal to 1 to 5 loved
graphic stuck draw at self dot car
rather gee textures cards self dot cards
i dot g area do g card quads at self dot
cars i dot what is it face suit and then
at self dot cards i dot that is value
right what was it oh sorry
suit and face
okay let's actually bring this down to
the next lines it's a little more
readable here and let me go into game
board let me go ahead and are we calling
shuffle on ourselves we are right yeah
we are calling shuffle so the deck when
it gets us instantiated it should be
shuffled right off right off the very
bat so I'm going to in here say self
draw rather self dot deck render and I
realized I didn't specify an x and a y
in the deck so I'm going to go over here
and specify that this should be I times
I minus one times 80 and 50 that's fine
right this is work no deck line third
deck on line 36 okay G core quads self
dot cards i okay do we have self taught
cards right yeah we do so I've got cards
i dot suit mm-hmm and the suit in the
face are both working right miss
anything maybe should I cut up on the
check you wouldn't cause each card II
represented by only one int but sure
this method is very intuitive
ah yeah Fisher Yates shuffle yeah a new
the shuffle I guess they're all the same
thing don't know I've seen the fishery
eights shuffle before that's been a
while since I implemented it so I had to
look it up on Wikipedia again but yeah
it's a pretty simple algorithm I've
messed up something here I'm not talking
sure what I've messed up just yet let's
look and see so we are we're doing the
the face is there right okay and then
the suit is good okay so let's make sure
that both of these values are correct
and this is correct let's try this let's
run it from the command line okay
okay so this is actually a nil value
self dot cards at a Y dot suit is a nil
value okay so what if I just print that
and I just print that it will still work
Oh interesting so the cards are nil and
why are the cards nil so is our shuffle
algorithm messed up then let's dump the
let's dump the cards and then exit can I
exit like that loved I event da quit
we'll do that okay so we're gonna dump
the cards and then quit just to see what
it looks like
wait self dot cards
okay so self dot cards is getting an
empty table interesting so if I do print
dump of base cards what's what's base
cards getting love die event dot quit
okay so it's getting all of the base
cards okay that's fine
okay and then new cards and then table
dot insert into new cards base cards at
random index okay is it maybe deleting
it and then deleting it and then the
reference to that object is therefore
getting
okay to be a little bit safer here's
what we're gonna do I think what's
happening is it's maintaining a
reference to the card in the other table
that's getting set to nil and so the
reference within our new cards table is
actually getting set to nil and in lua
anything set to nil in a table just gets
deleted from the table so we're getting
an empty table this way so instead what
we'll do is we'll figure out what the
cards suit is right so we'll say local
card is equal to base cards at random
index right and then we can say local
new card is going to be equal to a card
that gets the value of card dot face and
card dot suit and then in here well
we'll say zero zero and then here
instead of this we're going to add new
card to our new cards table and then we
can remove that card from base cards and
then this should fix the problem I think
let's try this out first I'm gonna get
rid of these print statements run the
code ooh
deck 30 9 reference and no value still
ok let's dump self dot cards
I need to run from the command line okay
so here's self dot event
okay wait oh wait hold on we're getting
13 cards wait why
waitwhat willing in 13 cards shouldn't
we be getting 52 cards toys 13 looks
like it which looks like one suit of
cards Oh self-thought yeah okay that's
fine that should be okay we're still
getting a group of cards we're not
getting the full 52 cards which is kind
of confusing
oh yeah you're right Babette cards and
deck one rent oh my I'm getting these
two confused all day today which is
beautiful all right so that's fine we
don't need to dump this anymore I don't
think this is gonna fix it we're still
having this issue the sort of run this
we can see that we are oh we're still
getting thirteen cards
really
really oh because I'm not dumping any
more right a dump self.cards
and Lodi even dock with I keep
forgetting to run it from the command
line okay so it's still 13 cards okay
that's weird so for the car all the
cards in the deck which is 52 until one
we don't even need we didn't even need
base cards actually we can use self Dot
cards this is acting as a proxy for self
cards so we'll just say self dot cards
so doing self dot cards we have new
cards self dot cards is gonna get
reassigned to this new cards table and
we're actually instantiating a brand new
card here instead of instead of using a
reference to the card that we are
referencing from self dot cards which
should be preventing the the nil
reference issue which we were seeing
before so if that cards is equal to new
cards okay random index okay
we are calling table dot remove on
random index
I'm confused why
so we dumped this before we dumped our
self cards right and it was all 52 oh no
it's only 13 okay
why wait why is that only 15 cards so
that cards for one until the cards in
the suit right which is 13 we're adding
a card of each type to self-thought
cards right that is wack
oh we are we doing a negative one
[Music]
oh I see what yeah I see what you mean
sorry Ki bum gonna Caillou Bunga I think
you're right actually
however I'm still not sure why whoops
numb my ass space one negative one there
we go to get rid of the disk area to the
event doc quit and the dump here scared
of this dump
okay there we go so Caillou Bunga was
right it was a stupid negative one issue
so thank you for bringing that to my
attention I'm surprised and catch that
damn so that we have five cards
rendering now the issue I have is that
this didn't seem to be rendering
fifty-two cards I'm just gonna make sure
as a sanity check that this is actually
rendering fifty-two cards because I
thought it was before I could've sworn
it was thirteen cards why are there only
thirteen cards here okay so cards for
one and every car to the suit right
I have hearts I have diamonds I have
clubs and I have spades shoulds that's
four cards right four times 13 is 52
that's weird
am I getting us am i doing a stupid
another stupid dumb bug here does dump
work without prints no you have to print
it out it returns a string I struggled
it earlier to figure that out
should be print dump oh yeah okay
actually if I was literally my mistake
I'm gonna be very sad yeah that was
always day
I'm very sad the whole time I actually
was like oh yeah you need to have you
need be printing dump duh like that's
obvious
I'm not even doing it in my course coat
man today has been beautiful alright
cool so that's that is working
everything is great everything is
perfect where am i creating the other
print dump that's printing the 13 cards
though because
that I'm a little bit confused about
what's here this is what was printing
the whole time silly me
awesome there's ten cards Jack nine
eight ten a s-- they're all the same
because they are being instantiated
before math dot random seed is done
actually so this we're going to put way
up here and now there are five different
cards and we could keep running this
over and over again thank you everybody
for sticking with me that was painful I
apologize
yeah lots of today's it's a troll troll
game that we've been implementing today
and it's been it's been a it's been a
ride it's been a journey this is gonna
be a long journey whoops I almost hit
myself in the face it's gonna be a long
journey but we're making our way there
it's been through over three hours now
we have a board we have a random card
deck we have the ability to click and
drag cards around which is pretty cool
I'm actually pretty excited about that I
think that's awesome these random cards
they don't have their update function
being called so I can actually click on
them and drag them around but that'd be
pretty cool you can envision the buggy
behavior if I were to click and drag
this card over here and then click this
both of those cards would then get
picked up so it can get a little bit
messy but things are moving in a good
direction next time we do solitaire we
are going to set up the tableaus all of
the cards are going to be laid out so
one two three four five six seven cards
we'll get the stock implemented with
drawing features that'll be pretty easy
to do we'll also be able to implement
the idea of stacking cards in our stocks
and probably the most difficult thing
that's gonna be on the horizon will be
picking up stacks of cards that have
been revealed to face up and making sure
that we also add to the tableau in a
sequential manner and things get
gridlocked to a specific area checking
for our click handlers on the top edges
of cards because we can click on you
know not just the card itself but also
cards
below it and cards that are just
partially revealed so we're gonna want
to sort of check for that too
so there's gonna be some sort of a
z-index issue that we're gonna need to
take into consideration but that's
actually not too difficult because you
can just basically iterate through the
tableau and check for iterate backwards
from the tableau essentially and check
for cards being clicked on or whatnot so
pretty feasible I would say why do we
add negative one to the loop says Indra
ready because we were actually starting
at 52 and working our way to one if we
go back to the deck which is down here
so cards in deck is 52 it's going to one
inclusive and if we say 52 to one it's
by default checking for checking to go
up and checking for less than if we say
negative one is checking for greater
than and going down so that's just how
Lua for loops work we it was a subtle
bug that I missed but some folks kindly
provided the answer in the chat so thank
you for the folks that did that and the
true Kinesis saying it goes from 52
downwards cool that's it for today's
stream on solitaire we didn't get as far
as I would have liked to get but we made
good progress we've covered a lot of
ground we did a lot of kind of low-level
stuff actually which is important for
sort of card based games like this
there's a lot of logic that goes into it
making sure everything fits the system
I'm going to make sure everything is on
github so if you want to tinker with
everything game board cards clickable
decks wren shuffle
oops if you want to tinker with the
codebase definitely by all means do so
it's here on my github account which I
had somewhere which I don't have anymore
interestingly enough let's go ahead and
go over there so I can paste the link to
the chat really fast for anybody who's
tuning in still and who wants to add
their own features before
extreme it'll probably be Monday I'm
thinking might be Monday Tuesday we'll
see if the next stream still isn't
enough time to implement everything but
let's go ahead and I just added it so
should be on my account or on my user oh
I just do this solve it whoops not that
solve its hair stream there we go a copy
that link gonna go over over here paste
in the chat so anybody who wants to add
their own features I actually recommend
that you try give it a try let me know
on the next stream if you do and you
have any particular way that you
approach the problem I'm going to
appreciate that cryptic the victory
animation I can't pull it all I can pull
it up actually will do that let's try
that oh yes
I mean it's doable but that's definitely
a very much a nice to have things so
we'll maybe we'll cross that bridge when
we come to it they in this case are not
updating the screen after they draw
everything which is how they get to get
this effect without incurring a
tremendous amount of lag but I'd also
have to figure out how in love today to
disable the reef the per frame refresh
because that would be a way to do it but
in any case that was a solitaire part
one we will go ahead and cut to this
screen I'll see if anybody has any last
questions and if not definitely tune in
tomorrow for our first time having Emily
Hong on stream to cover web scraping so
if you're unfamiliar with web scraping
basically using a script to parse a web
pages contents and or parse a bunch of
web pages contents using recursive
algorithms using what are called web
crawlers or web web scraper scrapers
which basically just recursively follow
links within HTML pages and analyze the
contents within them and let's see we
have booster booking says Apple Club
yeah kinda is swift worth learning for
the next ten years probably I'm not
involved in that space but it seems
pretty popular amongst people developing
iOS applications and whatnot which is
still very very much in vogue looking to
react native I'm not sure if that's
still as in vogue as it was last time
but Babic says what language will web
scripting be I think in Python I'm not
100% sure I don't think Emily specified
but I would assume Python and probably a
beautiful soup which is a really nice
scraping language scraping library for
Python and I've used it myself it's
actually pretty nice why are the twitch
descriptions basically empty while
YouTube has some explanation for the
streams that's a good point I should
start adding all of that information to
the twitch stream so actually thank you
for bringing that to my attention I
didn't actually consider that up till
now I'll start populating those with
information as well so good point good
thing to mention thank you the havoc is
saying that that reminded him of the old
windows dragging yeah because I don't
think they had a refresh on the monitor
for as often paddock says I have a
project in mind that requires web
scraping nice yeah I'm interested in
take a look at it I've done very light
web scraping in the past many years ago
but not anything recently so yeah can I
contact you for an idea as this boost up
again sure send me an email
see ogden at cs50 dot harvard.edu
chickeny says also reminder join cs50
discord and check out straw pulled me
for poles ah good point
I will take a look at that thank you
very much I want to sell it to intuit or
any taxes if it's financial in nature
boost I probably won't have any advice
for you so if it's I would maybe not ask
me for financial advice maybe if it's
coding related maybe but not not nothing
related to Finance which day for Salter
part two says w old W I think Monday
almost certainly Monday and probably
also Tuesday we are originally going to
have a code review session on Tuesday
but that has been postponed so Monday
and Tuesday will probably both be
solitaire parts if my sort of
forecasting is accurate
this looks like it's gonna take a couple
more streams to fully implement so I
would get some Monday and Tuesday the
stream will be updated the schedule will
be updated today so all of that
information will be finalized and you
can plan your schedule in advance all
right with that thank you all for tuning
in for solitaire part 1 Thank You Ashfaq
for the kind words we will see you
tomorrow for some web scraping enjoy
your weekend after that and we'll see
you also Monday and Tuesday for some
solitaire enjoy the rest of your day see
you tomorrow