all right hello world this is cs50 on
twitch my name is Colton Ogden apologies
for the microphone being muted I turned
it off briefly and forgot to turn it
back on this is part two of our stream
on solitaire also known as Klondike and
it's a popular card game or at least was
popular in Canada and the United States
last week I'm gonna transition to my
laptop
we ended things with things with a board
sort of like this with a little bit of
grid a grid layout in the background
some cards and this was just kind of a
test to make sure that we had our our
deck actually working with random card
draws in addition to the ability to
click and drag a card around there just
a sprite backing rather but you know
things are sort of moving in the right
direction but we do have a long ways to
go for example today some of the things
that I'd like to bite off are one
actually laying out the board in a way
that makes sense
normally in solitaire things are laid
out such that and we'll look at Google
Images in a second but cards are laid
out here in a sequence at the bottom
this bottom row starting with one card
then two cards then three cards and four
cards etc with only the top card being
visible you get a deck up here in the
top right which is important that's
where you draw cards from to put them
into more piles and then at the top
which you can't actually see because the
current algorithm is laying the cards
out at the very top left you're actually
stacking all the cards of each suit from
the bottom to the top from ace to the
king so to answer Amit's question the
topic of discussion is solitaire so
we're using love 2d today and the
framework love 2d is a really nice
framework for 2d game development you
can go to love to do org we talked about
this in the last stream episode
definitely check that out if you haven't
already seen it where we implement
everything from scratch including
parsing a sprite sheet of all our cards
laying out the grid creating a deck
class and a card class which we can then
shuffle the deck and draw cards from
which is very important because this is
sort of the backbone of our whole game
but more on that in part 1 part 2 today
is going to be much more about the
actual algorithms of laying out the
board getting to click-and-drag round
piles of cards and we'll see just how
much we
implement before we get to potentially a
part three if we're very lucky we'll
finish a part two but I don't think so
it's a rather meaty game so thanks
everyone for tuning in I got as Li in
the chat meow cat
I'll meet Microsoft India pika Mika to
that chat cat meow cat asked while I
talk about machine learning probably not
machine learning today I'm not a machine
learning expert but it'd be nice to get
somebody in the future who is more
well-versed in machine learning such as
maybe Nick Wang who did a prior stream
if you haven't already watched the
stream on binary classification with
Nick Wong definitely check it out it's
on YouTube probably not on Twitch
anymore it was one of our earlier
twitches and those only save for 30 days
but yes we are indeed continuing to make
solitaire iMeet microsoft india says
please share the link yes absolutely so
I'll share two links in the chat here
let me just pull up the repo name so I
remember 100% what it was I have the
code from last week on github so if you
are tuning in and you want to clone the
code if you end up cloning the code now
if you're watching this on YouTube
chances are the codes not going to be
the same as this right at this exact
moment in time luckily you can download
our betray commit if you want to
unfortunately for some reason github is
taking a long time to load I'm not
entirely sure why but it looks like it's
working I saved it as solitaires stream
so I'm gonna type this into the chat
here hopefully this doesn't cause any
issues I just eliminated the macros on
this machine so that I could actually
type stuff this week github.com slash
colonoscopy slash solitaire stream take
that and that should allow you to
download the repo if you don't know what
love 2d is and whoops I just ended up
switching my view to the wrong one again
if you don't know what love 2d is you
follow that link download it it's a
cross-platform framework for making 2d
games
hence the 2d in love to do unfortunately
doesn't let you make 3d games I'm
waiting for the day love 3d comes out I
think that would be amazing
development but alas it is not a real
thing yet so solitaire for those
unfamiliar let me just pull up an image
of the solitaire starting layout so we
can continue and sort of have a visual
goal of where we're going next
this is where we're going next it's not
gonna look quite like this this is a
little bit fancier texture work done on
it but you can see that the grid is
actually very similar to what we laid
out last week you have seven rows of
seven columns sorry in the bottom row
here these are your stacks tab blows
because of different terminology that
I'm not 100% clear on and you can notice
that the cards start off on the left
with one card being drawn and that one's
face-up the second column has two cards
the top of which is face-up the bottom
would Fitch's facedown the third one the
top card is still faced up but every
card is faced down and you can see the
pattern continues on until the seventh
column so you get all of these sort of
areas to start laying out cards from
left to right and they increase in going
to in that direction going towards the
right a one at a time at the very top
left this is where the actual game is
won and we haven't covered this in too
much detail yet but by stacking every
card of each suit so remember there are
four suits ace time and spades clubs so
by stacking every card every ace cur
sorry every diamond card every hearts
card every clubs card every spades card
from a stick King that's how you
actually win the game and so what you're
looking for when you first start is of
course an ace because if I if I find an
ace well I can stack an ace here or an
ace here or an ace here depending on
which suit it is right and that's it
gives you the ability to then lay a two
on top of that and then a three on top
of that and by the time you finally make
your way up to King you've won the game
if you get all four of them out and to
get new cards which you can lay out
either here on any of these piles or on
these for winning piles you have the
deck here that you can draw cards from
it's also called the stock and so if I
draw for example in a stright here I
could put that in one of the piles or if
I draw a for example a and it goes lower
value down if I were to draw a three a
black three I could put it on top of
this red four right because the cars
that you layout on all of these this is
an important rule of solitaire when
you're laying cards out on your seven
piles they need to alternate in color
and they need to go from top to bottom
they need to go
came down to down to ace so this for for
example I could put a black three either
a club or a spade three on this four I
could put in ace on this two but I'd
probably want to put the ace on one of
these piles here so I can start building
up my my winning piles right I want to
put the ace first that's the card you're
looking for I could put a black eight
right here I could put a red queen here
I could put a red six here a red seven
here a red to here and this is how you
build up your piles that you can move
around eventually if you build all your
piles in descending sort of order
amongst your seven tableaus
you can very easily take cards from any
of these piles and then put them in your
winning piles and so this is a refresher
on how the mechanics of solitaire work
and so that we have a clear picture of
where we're going as we implement our
game an important thing that I think we
should first think about implementing is
populating these seven columns down here
in this bottom row I also probably want
to get rid of this drawing these five
random cards and then maybe also just
rendering a card backing here and
that'll be representative of our deck
tux man thank you very much for tuning
in to the stream and thank you very much
to Kay's oxy and South Africa for the
follow us right before the stream
started and again any questions on the
rules or what we've done so far
definitely leave them in the chat I'll
be watching that as we go along
twitch.tv slash cs50.tv as well alright
so let's take a look here so the what we
did last time was we implemented the
game board and what this was was just
are basically just drawing the screen
green and then those rectangles though
the grid layout for where we want to
place our cards and that's essentially
the backbone of where we're going to end
up placing stuff and of we're probably
gonna want some notion of a card pile
later on which has a bunch of cards in
it and those cards are gonna have to
enforce their order and they're
colorization so we're gonna need to
worry about that in a little bit what I
want to do is I want to get rid of these
sort of arbitrary rendering that we
already have so what I think I did was
in the deck class I made a render
function here that just drew the first
five cards of the deck
I don't really want that I don't want to
draw those five cards anymore so I'm
actually just going to pass on that and
re-render it and notice that now we're
no longer drawing those five cards and
we indeed have our grid layout as we saw
previously right I also probably don't
need this random card that I can click
around I can get rid of that pretty
safely we're implementing we implemented
it such that I can click to start the
drag and then it'll just follow my mouse
and then to click again to undress or
under AG the card and some are 1318
thank you very much oh thank you for
cool hairstyle thank you very much for
the car for the compliment I appreciate
that so I think in card actually we may
have been doing that in here let's see
it might have been in Maine actually
let's make sure yeah I think yeah we
were rendering a Queen of Hearts we
chose to render a Queen of Hearts just
as a test to make sure our card class
was working you can see here in my
directory and this needs to be shrunk
down a little bit I can get rid of some
of these but notice that I have a in my
source directory in the repo and if
you've cloned the repo then you'll
you'll see this I have a card class
which is just representative of what a
card is which stores a suit and it
stores a face value which are two
important things that we need to take
into consideration for our algorithm
we'll need to check to see one when we
place a winning card down in one of our
top tables up here we want to enforce
that each of these piles is just one of
the same suit right hearts diamonds
clubs and spades when we want to
actually stack them we need to worry
about the face value whether it's a 3 or
4 a queen a king and we'll do that not
only here in the winning piles section
of our code where we're also taking into
consideration the suit but we're also
going to need to take into consideration
well actually we need to take into
consideration the suit and the face
value when we lay it down on the
tableaus too because remember we need to
enforce a red-black sort of progression
of cards down the line now it doesn't
need to necessarily be one suit or the
other a specific one it just needs to be
one of two if it's a red card if it's a
heart or a diamond the card needs to be
clubs or spades in order for us to lay
it down and vice versa so that's just
one thing that
take into consideration so that's why we
have a card class the card class
maintains a reference to its face its
suit whether it's in whether it's picked
up and it's x and y value so that we can
render it to a given place on the screen
there's also a deck class which just
maintains a list of cards that are all
shuffled we wrote a shuffle algorithm
last time the somebody refresh my memory
on what the the shuffle a beta was it a
Yates shuffle what was it
Bates shuffle and also known as the new
shuffle I think that was what officially
eight shuffle that's what it is
essentially just taking a bunch of
random basically indexing into our deck
at random putting it into another
temporary deck and then eliminating that
from the prior deck which saving us a
little bit of sparsity we don't need to
keep roll reroll oranda MS ation if we
end up messing up sort of how we take
cards out of the deck and also shout it
to David for tuning into the stream and
it sucks my looks like Tuckman's about
to say something for the card placement
within the rows as well so that was what
we did with the deck class very
important we'll be using that to draw
individual cards for our stock later on
in the game we needed two dependencies
modules so that we could actually not
only specify where our textures are laid
out but also to splice them apart and
store a reference to the quads that we
used in the last demo of the last video
which were just rectangles that
represent a chunk of our texture because
we don't want to draw our entire sprite
sheet recall and we'll pull this up here
the actual sprite sheet for our game is
this large chunk of graphic right it's
all of our cards put together into one
image and we don't obviously want to
draw that anywhere in our game and when
I draw just a piece of it so we define
what's called a quad or rectangle I'm
short for quadrilateral just an XY and a
width and a height and by passing that
into a function in love 2d
it'll just draw that piece of the
texture I won't draw the entire thing
and that was a part of the last stream
tune into last stream for how we
actually implemented that we wrote a
couple of functions we had to end up
actually fixing our graphic a little bit
because for some reason some things were
out of order and even after we did that
cards were still in the wrong order
Queens were coming before Kings and Ace
was coming before 10 it was kinda
mess but we fixed it in code which is an
important lesson I think even dealing
with graphics and this has come up in a
some comments as well when dealing with
graphics that you don't have any control
over their layout sometimes you do have
to encode fix things yourself so it's an
important at least lesson to be aware of
ideally though work with an artist
specify for them
I need graphics laid out in this way I
need everything laid out ideally in a
systematic way so that you can
algorithmically sort of splice things in
a clean way but you know you don't
always have that luxury you won't always
work with an artist and you might not
always be talented like myself
sorry you like myself will not be
talented enough necessarily to fix the
artwork that you were given so sometimes
you have to use code instead of you know
digging into it with Photoshop or
or a sprite or etc will this solitaire
game tell us when we have no moves left
and we have effectively lost we can
implement an algorithm for that short
all we have to easily do well is it
gonna be easy to do necessarily I think
so because you often you just have to
iterate through all the card piles check
to see if they have an available move
and if they don't have an available move
and you can't move your cards to the
winning piles then you've effectively
lost including your stock so yes it is
definitely possible in my blackjack game
I just picked a random position from an
ordered deck yeah if you're referring to
the shuffle yeah that's effectively what
Fisher Yeats is but just a little bit we
had a little bit of a refinement on
Fisher gates and harder projects thank
you very much for the kind comment as we
sang you're very talented remember the
awesome flag pixel art I appreciate it
but I don't know if I would go so far as
to say that but I very much appreciate
it I wanted to ask for the placement a
black card for example would it be
simpler to use
Hart or diamond or add an additional
value to the card as red I'm inclined to
say that since red is a derived value of
properties that we already have in the
card we probably want to just keep the
heart or diamond and just use an or in
that case rather than create new value
that we can derive from the existing
value and there's an argument to be made
for against this but I think the only
time at which you want to consider this
is when it's very computationally
so I'm I am more inclined to say we'll
use an or in that case and not add add
new data that we can easily just derive
with a simple condition cool so we have
the board all laid out we were just
looking at the different modules
dependencies were restored in parsed all
of our texture data the game board was
where we actually drew the background we
can draw a deck to are gonna end up
drawing all of our card piles which are
gonna be very important because we're
gonna have different stacks of card
piles and then we also had a util
function and the Ute RI you till module
rather a file that you told that little
file which had a few functions in it for
parsing our our texture for quads so
splitting it up into quads and also
fixing the fact that they were unordered
when we parsed them and we also used the
beautiful tool called stack overflow to
find a function called dump which just
recursively prints a table because I
didn't feel like writing it from scratch
ourselves but all it does is just writes
out a table depending on if it's a table
or not it'll output the value it can I
sleep its brackets or curly braces to at
least tell you that you're working with
a table and will recursively call itself
and then to string H each nan table
value so that you can eventually see
your entire layout of data and then we
had a resort function that ended up sort
of putting our cards in the right places
so that is a rough breakdown of what we
did last week now the first thing that I
want to do so that we're at least
visually seeing where we're going and
sort of sanity checking the flow of our
game feeling more accomplished than we
might actually be is laying everything
out on the bottom row so let me go ahead
and go back to deck so that it renders
what we what we saw in the graphic
recall was that the piles from left to
right start with one cards then two
cards then three cards four cards five
cards six cards and then finally seven
cards the top card is always face up the
bottom cards are face down and you
reveal cards as by taking cards off of
them so for example in this second pile
and I'll go to the image here in Google
if
take this too off of this card down here
I can flip that card over and we'll
implement this with right click probably
I can flip that card over and it becomes
a card that I can now move wherever I
want to move it if it's an ace well I
just revealed an ace I can put it in one
of my winning piles if it's for example
a black three well I can put a black
three here and then maybe move this King
over here because you have to end up you
I believe it's a rule where you can only
put a king onto an empty slot in your
tableau I'm not hundred percent sure
about that actually solitaire move card
to empty tableau yes if any of the
tableau piles are empty you can move a
king there right okay so that's good I
am saying you it has to be a king so if
there's an empty slot let's say I move
this to right here let's say I move that
onto an ace pile up here let's say I got
an ace put it up there I was an ace of
spades put it two up there on top of the
ace of spades I'm building that that
spades pile up now I have this blank
card here let's say let's say that's a
black three I move the black three onto
this for now I have an empty tableau I
can put this King over onto this empty
tableau and now I've sort of opened up a
new pile that I can start digging
through and this is sort of the the
fundamental way of playing the game loop
the loop of the game is just kind of
revealing cards moving cards around
until everything sort of falls into
place but yes that is the flow of the
game regarding the schedule is South
Africa off by a day because it's Monday
here the schedule should be up to date
it might just need to be shifted one day
over one card two cards I'm getting a
Mario dot C vibe here
oh yes only on an empty spot one card
two cards I'm not entirely sure what
you're referring to if you can clarify
that for me
100% sure okay so let's go ahead and
think about what we're going to need to
do in order to well first of all we're
going to need to move cards around and
not only are we going to need to move
cards around but we can actually move
piles of cards
from our tableaus so we will need some
notion of a card pile right and at least
this is how I want to frame the game you
could frame this in a multitude of ways
you don't necessarily need to abstract
it in this specific way but I'm inclined
to say that I'm probably gonna want a
card pile class and this is all from
scratching off-the-cuff but this is just
how I go about approaching problems like
this by thinking about the objects in my
space the sort of interactions are gonna
have and sort of building up the the
building blocks that I'm going to end up
actually composing to create my game in
this object-oriented way so this is
going to be a card pile class a card
pile class is kind of like a deck but
it's not gonna have a shuffle method
it's going to have the ability to I
think move around necessarily yeah
probably we can also implement this in
another way what we could do is we could
have each individual card parent other
cards we could have it such that this
nine for example is a parent of the
eight below it and that eight is a
parent of the seven below and so there's
always this direct chain of parenting
right where you have a card that's a
parent of a car that's a parent of the
card kind of like a list almost almost
like a linked list and what we could
therefore do is by moving a parent you
move the child mmm by moving the child
you move its child because we could just
have each card reference its parents
position and by doing that by just you
know calling update and you know moving
something and checking to see whether
its parent is in a different position we
therefore can move multiple things at
the same time so this is probably the
route that we're in going to end up
taking nested for-loops like Mario see
from this oh I see oh right yeah it is
kind of like a Mario pyramid now that
you mention it it's kind of like a Mario
pyramid that's been rotated 90 degrees
to the left I agree yeah it's kind of
it's very similar to that this one's a
little more complicated just because we
have to enforce that the bottom most
card rather the top most card is always
four
up so we will be we will be doing that
so now I'm actually wondering whether
it's even necessary for us to for us to
implement a card pile class because we
could just enforce this parenting in
this piling behavior almost emergently
using just basic parenting so that might
be that might be a place to start why
don't we start there so rather than we
won't worry about card piled out Lua too
much just yet what we will do is we will
go into card and we'll say that every
card should have a parent right or at
least it should have a parent field that
we will eventually care about likely and
I don't necessarily think that it should
have a child or we should necessarily
need to worry about whether it has a
child we can probably just assume parent
and that will be fine we will actually
care about whether so I think we will
need card piles for the winning piles we
will need and those are actually going
to be rendered differently because
notice if you look at well it won't they
won't be clear here but if we were to
for example pull up a this is
interesting they actually have to this
is a different version of a solitaire it
looks like I mean find an image where
they have cards that are already laid
out for example let's see solitaire
let's do solitaire in progress so here
for example you can see that they have
things shifted a little bit it's kind of
lit it's kind of mirrored not mirrored
but flipped sort of vertically towards
the right oh it's all along a vertical
flipping point it's foot horizontally
but you can see that the winning pals
are on the right side here notice that
there's an ace here so this is the
spades winning pile this is the hearts
winning pile you can see that there's a
2 there which means somebody already
laid in ace and then a 2 but they're not
being rendered vertically down they're
not sort of like they don't have this
cascade not cascading effect but sort
this shifted offset sort of rendering
effect that the piles the tab blows have
on them right all of these are sort of
rendered vertically such that you can
see them the cards that are directly
below any given card and this is useful
because we care about that information
we want to ensure that we keep
everything in a particular order and
then it's off suited these we don't care
about we know we can we already know
always that we have the the all of the
spades here all of the hearts here
diamonds clubs however it's ordered so
we will need to change our rendering
logic from both of those use cases this
particular area up top is going to
probably implement a we might be able to
reuse the deck class but you know
semantically is not that's not accurate
so a card pile probably is accurate we
might be able to just use it for that
and then use parenting for everything
else and so that's probably what I'm
inclined to do so the card piles will be
used for the winning piles it makes more
sense probably at that point to then
just call it a winning pile right so
rather than having an overly generic
class since we know that we probably
won't use card piles for the other areas
of our of our of our game board we don't
necessarily need to distinguish between
the different piles so well we'll sort
of write in winning pile right now we'll
come back to it later we'll worry about
it later in the meantime what I do care
about like I said is laying out all of
the board and then testing our
interactions testing parenting making
sure that's all working so that we can
start clicking and dragging cards in the
right locations so back to the card
class which we are looking at up here we
have a parent that's going to be sort of
kept within that class so this will
refer to any of the card this will refer
to a card directly above another card in
the context of solitaire and actually
let me see
the parents are actually gonna be
rendered below so the child cards like
so eight here is a child of nine so nine
is so eight has a reference to nine as
its parent right nine has a reference to
ten as its parent ten has a reference to
Jack Jack as Urban's to Queen and Queen
as a reference to King as its parent and
by moving Queen right we will sever that
parent-child relationship which is an
important thing we need to do so that
they don't get rendered or they know
that we the King doesn't follow the
Queen well sever the relationship
between the king and the queen and then
we will make sure that all of the
children refer to their parents for
their position so if the eight is saying
make my position my parents position
make if the nine is saying make my
position my parents position etc but
with shift with a shift
obviously like 15 pixels by moving just
the parent we will effectively move
every single child as well so this is
nice this this is a very simple way I
think of looking at the problem so the
self thought parent is gonna be nil
right now we're gonna worry about that
in the meantime let's go to our deck
class and then I'm going to say rather
not deck class sorry game board class in
here what I'm gonna do is I'm going to
store actually already sort of sketched
it out last time we have seven tableaus
here and so I'm just going to shorthand
right now I think I'm just going to do
this right so I have one one well
actually no sorry we're gonna have seven
tableaus like this these are empty
tables so we have 1 2 3 4 5 6 7 and we
can we could probably do this
algorithmically so well consider doing
that as well but just to sketch it out
so we know what we're doing
crazy fluke okay guys how are you
tonight and cervixes hi everyone hello
we're gonna sketch out the layout of our
tableaus right here so the first tableau
remember if we're looking left to right
yeah the first tableau is going to start
with one card so I can just say
actually what we can do is I can say
self dot deck and then I want to draw a
card
right that's effectively what it what
it's going to look like and then we're
gonna do it two times here three times
here four five six and seven all of
those cards are going to be face down
they need to be face down by default
except for the last card the the what
will end up being the ultimate child of
that stack that child will be face-up so
this is essentially what its gonna look
like and what will end up it will also
look like for the second pile for
example is something like this right now
self dot deck sorry I called it self dot
draw should be self dot deck and self
dot deck draw it'll look like this and
it'll sort of add more and more and more
and when Marcus remember going one two
three four five six seven cards so
clearly this is gonna look a little bit
bulky we can do this in a loop a little
bit more effectively down here so I
could say for I equals one until and
we're just going to again adhere to good
design I'm going to say here we'll say
num tableaus is equal to seven so back
to the game board from one until num
tableaus do tableau is kind of a tricky
word and again last time I remember vs
code is having issues with little
formatting so if you're using vs code
with the newest version my apologies
it's a hurting me as well
I should probably have not updated but
alas I did for from one to the number of
tableaus we're effectively going to do
what's in this this call right here so I
can say self dot tableaus
Macie well the table dot insert into
self dot tableaus a new table and then
what I'm gonna do is I'm gonna say for J
gets one until I because there's one
card for every row there's seven rows
seven columns sorry and each column has
AI cards right column one has one card
called 2's two cards called 3s three
cards so therefore we have another loop
that's just gonna go up until I and just
draw that number of cards and put it in
the right position in our tableaus in
that particular tableau right so I can
say for JA where J is one until I I'm
going to table dot insert into self dot
tableaus at I self Dec draw and I can
delete this right here well what I have
to do it first to say stuff that
tableaus is equal to an empty table
which is gonna become a 2d table here
pretty soon and then we'll just say
populate all tableaus with starting
cards and down here in the draw or in
the render function what I want to do is
I want to render so that we know that
this is working I want to render all my
tableaus so I can say for I is equal to
and actually I need to figure out where
we started our our actual grid indices
so first of all let's make sure that
that runs so let's go ahead and do that
um it did not so oh we didn't implement
the actual draw function in our deck so
you need to do that so over in deck I'm
going to say self or sorry function deck
draw and what this is gonna do is return
a card from the deck and remove it
because we want to draw a card from the
deck but we also want it to not be in
the deck after we draw it because
obviously if we draw a card but we keep
it in there we just return a copy of it
well
our numbers are gonna be skewed we're
not gonna be dealing with 52 cards we're
gonna be dealing with infinite cards at
that point so it's not gonna work
blue booger says a 2d table make 3d
solitaire stack the cards in three
dimensions always with the good ideas
blue booger keep them coming
that's a that would actually be pretty
cool though I'm not gonna lie
I'd be interested to see how that would
actually be implemented I personally am
Not sure fan Mogi at 21 Georgie la ley
and see Marie tea I have a very low font
size on this monitor I can not read that
to save my life
cm RL jrj thank you very much football
and Georgie la crazy flogging the stream
started for long
this hasn't we haven't we haven't been
doing this particular stream for too
long but we did do a part 1 so we are
progressed a bit beyond just them you
know very beginning of a love 2d
application so if you haven't checked
out solitaire part 1 highly recommend
watching the first part so you can see
how we built a deck how he built our
game board how we parsed our texture and
we did a bunch of other things this
particular instance builds upon all of
that source code beacon you can catch
that on youtube.com slash cs50 look at
our art which playlist and also in which
we have the vods tulip at the time of
this recording it may not be on at the
time you're watching this in the future
okay so we have our deck Claudette class
with a draw function that we need to
implement so we can actually get a card
from the deck and then remove it from
the deck so what I'm gonna do is I'm
going to say a local card is equal to
and actually we ran into this issue
before so what I think what we need to
do is make sure that we're making a copy
of it so I'm gonna say local card from
deck is equal to and actually think
there's a there's a copy function but it
might work funky with classes so we're
just going to copy the card effectively
and then remove it from the deck because
all we're effectively doing if we recall
is just storing a a face and a suit
right that got that right yeah a face
value and a suit one of four values so
that's all we really care about
so I'm gonna say card firm deck is gonna
be equal to self dot cards at math dot
random number of self cards so remember
the number is the length of a table so
if you have 52 cards gonna give us
number 52 if our deck is only up size 40
or 30 it's gonna give us that number and
so we get a proper number between 1 and
the upper bound of our deck which is
important let me just make sure that
it's indeed self dot cards I'm going to
say local card to return is equal to a
card that's gonna have card from deck
dot face I think this is right face and
suit yep
and then card from deck dot Val wait
what did I call it suit I've been having
a hard time keeping up with suit and
face and value all these words that I am
very bad about remembering but now what
we can do is we can say oh actually what
we also need to do we need to store our
index so card index is gonna be equal to
this value right here I'm gonna replace
that with card index I'm going to do
that and then I'm going to say self dot
cards at card index is equal to nil
actually better would be table dot
remove self cards at card index which I
think underneath the hood just does do
an illegitimate to nil so that way
because in lua if you have a nil index
in your table it effectively just
condenses the table back together if I'm
remembering correctly and so table don't
remove effectively just does that exact
thing but we might as well just do
what's more conventional I think table
not remove self dot cards at card index
so if we drew a card in the middle of
the deck the deck gets sort of
compressed inwards to accommodate that
and now it's no longer 52 cards long
it's 51 cards long and what I can do
then is I can return our card to return
so now we have our new card that we're
placing somewhere in our game we don't
care where it is but not only do we have
a card that we copied from our deck we
removed it and so now we were preserving
sort of the gameplay mechanic of drawing
a card from a deck very important thing
to consider if we didn't do it this way
we would have in
vennett cards which would not be ideal
or would have bugs with ya signing cards
to nil in our deck and them being nil in
all sorts of places
cool so our game board is the next place
we need to do this all right what we
were doing is we were testing right so
now what I want to do is I want to draw
all of these cards that we've just
allocated to our seven tableaus so these
are the seven tableaus I want to draw my
remember we have seven tables now that
fit those tableaus I want to draw one
card two cards three cards four cards
you're looking at it in reverse
direction because of its flip because of
the camera one car two cars three cards
four cards we're gonna do it that way
and so generate tableau is I don't think
oh you know what I was gonna do this is
gonna be the generate tableaus function
so self-generate tableaus and then I can
just copy and paste that into this empty
function which we must have written last
time because I don't think we wrote it
this time I think we wrote this in
anticipation of what we needed to do for
the next stream so now we have a
generate tableaus function we sort of
have shrunk the size of our constructor
this is our constructor we don't want
too much code in here this is where you
know the object gets instantiated well
all of our values get initialized I'm
having a bunch of logic in here kind of
bloats it makes it hard to keep track of
what's going on so we just made a
function instead so let's actually draw
each individual tableau and what we're
actually doing that is we're doing it
here right we have a function yet but we
do have seven rectangle calls that are
effectively functioning similarly to
them and so I still want the grid to
draw in case I move cards away from you
know the tableaus just thinking ahead a
little bit yeah so this is how we're
going to need it and I think that should
be fine here we're effectively going to
check for cuz that we're gonna have
tableaus we're gonna have cards in those
positions these seven tables are where
we're always gonna store the cards no
matter what
if we move cards around between tableaus
we're not actually storing card pile
objects and mixing and matching those
and I actually think that would get
relatively complicated and kind of hard
to maintain are too hard to reason about
a little bit so we're just going to draw
each tableau individually and all of its
cards and those parent-child
relationships that we talked about
earlier on are going to help us make
sure everything looks and functions in
the same way so what I'm going to do is
for I is equal to one until num tableaus
do so we're just going to iterate
iterate over and draw cards in tableaus
tableau grid markers just to
differentiate them to be Morse more
explicit about we're actually drawing so
I'm going to again we need a nested loop
within this so we're iterating over r7
tableaus but we also need to iterate
over the cards and the tab blows to
actually draw things out so I'm going to
say for J is equal to 1
until tableaus I number of tableaus I do
and because the tableau tableau is at I
is going to have a length of cards that
we need to render and this will this
will change over time and it's gonna get
a little more complicated when we
actually need to draw them in the right
order with the parenting but this should
still be doable things should still have
it structured ideally such that will
preserve the rendering order so that we
can iterate over the cards in the right
order and draw everything out and the
parent-child relationship will be
preserved
whoops Drake 23 says hello that's Nate
shout out to Nate thank you for joining
our stream so here we can say so we have
a place here so these are our actual
individual tableau locations and
there's a mathematical operation that
we're playing here which is 10 plus 80
times I minus 1 in this case so see 10
plus 80 times I minus 1 so I is 1 minus
1 is 0 80 times 0 is 0 plus 10 is 10 but
you know plus 1 is x 1 is 90 and then
172 53 30 so we're just shifting
everything by 80 pixels so we'll
maintain that relationship here as well
so we'll say and we card does have a
render function correct it does so we'll
say tableaus I render at 10 plus 80
times J or I minus 1 and at y-value 160
and these should be these are kind of
temporary variable values because I
don't necessarily know where I want the
card grid to be drawn tableaus to be
drawn eventually right now we're just
kind of getting everything in place we
can easily add a margin value and shift
all of this and change our our game size
so that it's a little bit maybe a little
bit closer up so things look a little
bit more interesting it's a little bit
zoomed out now because the textures are
kind of small so we'll worry about that
in time right now let's just get that
the logic correct and then let's let's
figure out the values that we want at a
later time and then get everything
rendering perfectly also shoutout to
Andre thank you very much for joining
the stream and Nate don't be sorry that
you're late it's ok you can definitely
watch the the Vata the vaad and scroll
back and watch on youtube at any point
so this should work now the only problem
is we want to draw all of our cards but
if we're drawing them all at the same X
Erling them all at the same y-value
we're not gonna preserve their stacking
right where they're all gonna be
directly on top of each other which
doesn't help us
so this 160 we can actually add maybe
plus 10 times J minus 1 right because
the friend J cards right fret now if J
is 1 then we'll just draw it at the
right we'll just you know 1 minus 1 is 0
times 10
zero so it'll just shift it by zero
pixels but if we're at J 1 or rather J 2
and we minus 1 well then it's 1 times 10
and then we'll add 1 we'll add 10 pixels
to our drawing and then 20 and in 30 and
so that will give us that stacking order
as we draw so let's do that and let's
actually see if this is working it is
not global tableaus which is a game
board line 58 which yes self dot
tableaus and self dot tableaus at I
let's try that method render a nil value
game board 59 interesting so self dot
tableaus at I at this point is supposed
to be a card and this is a problem with
dynamic programming languages it's not
always clear that you're gonna have the
right data in the right place when you
run your application if you're using a
statically typed language like Java then
it can actually check to make sure that
you're putting things in the right
container but if you're not doing that
if you're using Lua or Python or Ruby or
some other languages dynamically typed
then you're gonna kind of have to cross
your fingers sometimes just make sure
your logic is sound which mine always
isn't as we can clearly see here so at
line 59 attempt a call method render
which is a nil value so card is nil at
least what we assumed to be a card in
self dot tableaus is nil so let's see
whether our logic is sound so we have
game board generate tableaus from 1
until the number of tableaus we are
inserting ah right so self that tableaus
at I actually write because needs to be
I J right because we're rendering we
were trying to render our entire tableau
table at that point we need to actually
index remember we're storing a table of
tables and each table each nested table
contains cards right so that's what we
needed to do we need to index into the
right tableau and then we need to get
the right card from the tableau which
now it's it's not rendering anything but
at least our logic is sound so let's
figure out why that might be that's an O
you know why because they're not being
assigned
well actually they aren't being given an
X in a why that's what this is here
right um you see what why is that not
working this is odd now we didn't make
self that hidden true did we card let's
see if the render function is so card
back right okay and we want the car to
be hidden on well we don't want them to
be hidden necessarily what we're going
to do the next part of what we're gonna
do is we're gonna actually hide all the
cards beyond the last card so we are
gonna need to worry about that but at
the exact like this exact moment we we
want everything to sort of be visible so
let's not worry about that just yet
instead let's figure out why the cards
aren't rendering so it looks like we are
getting cards up here which aren't
clickable this is the Queen of Hearts
that we had before everything is
rendering up at the top left
oddly oh you know what it is it's not
actually rendering at X Y it's rendering
at self dot X and self dot Y so we don't
want to have that happen we're going to
just use X&Y self dot X and some thought
why are not being assigned appropriately
at this moment and that's okay we we
will worry about that later but now you
can indeed see and this is very
satisfying to look at that all of the
cards are rendering in the right place
in the right order now they're not being
shown card backings necessarily in the
correct way we can we can work our way
backwards and do that we're going to
essentially mark them all hidden and
then mark the top card as visible and
that will solve the same purpose but
it's a nice beautiful sight everything
seems to be going according to plan Adam
saying it's looking very good and as
saying that's awesome I know I I very
actually have not never implemented this
myself so seeing it for the first time
I'm seeing it for the first time with
all of you so I I great I get great joy
out of
making a game that I've never made
before for the first time like this it's
it's a very satisfying fulfilling
experience these cards aren't actually
interactable but the Queen I believe is
now the Queen's not interactable either
oh the reason for that is we're not
calling update on each card normally we
do that and that's actually where the
logic for moving the cards around takes
place so we'll need to do that in order
to move things in order to move each
individual card but that in due time
let's shift the cars down a little bit I
can't actually read what they say and
that's kind of a problem I'm going to go
over here and where I actually render
them I'm gonna set this not to 10 but to
20 let's see if that is a little better
there we go that's pretty good I can
kind of see what the cards are I can see
what the suit is which is very important
I can definitely tell well with the
exception of the jack I actually can't
see what the jack is and so for that
reason I'm actually gonna bump it up to
30 because it is an important
consideration there we go
that I think is close to perfect we can
see the suit for every card type whether
it's even a face card or a number card
and we can see the number very well the
face and then and the suit are all great
in ways you're saying pretty cool it
looks really close to what I play that's
awesome I haven't played solitaire
myself for a long time I think I was
actually think it was your age Nate last
time I played solitaire on a mild
Windows 95 computer back way back in the
day so this is this is moving along
right we accomplished our first goal
which was to lay out all of our cards in
the right order right we sort of did
Mario and the Mario sort of pyramid
approach to things with the nested loop
and this is a common pattern that you
see all over the place this isn't just
in the context of Mario I mean it's what
most games I would I would even say have
some kind of two-dimensional aspect to
them whether it's splicing textures or
drawing tile Maps or Lang cards out in a
grid or even in match-three which some
students have just done Adam might have
done match-three as well fairly recently
you have two-dimensional layouts it's
unavoidable and very important to
understand how those work excuse me
cool very satisfied at how that looks
and it's rent it's different every time
right
yep completely different it's wonderful
now it's not it doesn't quite look how
it's supposed to what it's supposed to
do is show only the top card so let's do
the all the cards below the top let's
make those hidden and keep the very top
card set to not hidden we can do that as
by simply saying here not here but in
the generate tableaus I can say
[Music]
if here we'll do it in here right so
ensure topmost card is set to visible so
I can say if J is equal to I right
because that'll mean we're at the we're
at the sort of the top layer of our loop
right then I can say I hate the fact
that the auto for the formatting is
messed up I have to tab like a million
times now that's okay they'll fix it
they probably already have fixed it I
probably should probably should look and
see if they have a an update I can pull
from github or something but I can say
if J is equal to I which will mean that
if we're at the end of each nested loop
or regenerate or we're displaying the
cars in our tableaus it's going to be
stored at self dot tableaus I J dot
hidden is equal to false and then what
we can do is just assume do we want to
do that it doesn't really matter at this
point it's kind of up to your taste I
guess well be explicit we'll just say L
self tableaus or we can do actually as
will just say self dot tableaus i dot or
i J dot hidden is going to be equal to
whether J is equal to I so now hmm
is that correct equal to whether J is
not equal to AI
yes and what that does is that does have
the effect that we are looking for of
the cards stacking in the right way and
someone actually brought up an
interesting point which is that I can
leave the margin at 10 while the cards
are face down and 30 once they're face
up because otherwise you might run out
of room once we zoom in that's a good
point and actually I think I'm going to
do that and what we can do is we can say
local padding is equal to 160 time or
local we'll say local yeah we'll say
local padding is going to be equal to
[Music]
self dot tableaus I dot J dot hidden and
10 or 30 and what that ends the problem
with that is that now our our shift is
messed up so we actually need to
maintain a counter to where we're
shifting everything by so what we can do
and by the way this is how you do a
ternary statement at low I use and/or so
it's basically evaluate this boolean and
then we'll do this one if it's true and
ten and or thirty if it's false just by
the way that an and or evaluates the
truthiness and false in this of values I
figure off hand the exact semantics but
the pattern and or for a ternary
operator which you might have seen as :
question mark colon and other
programming languages it's a pretty
common thing to see now the issue is if
we assume it that way then yes things
will work up until we get to the actual
cards and then those are calculated sort
of absolutely we're rather than
relatively they should be relatively
calculated and so instead and this is
where things are gonna get kind of
complicated especially as you start
moving cards around well
necessarily actually this should this
should not be a problem because we will
always have hidden cards at the bottom
of the piles and then revealed cards
towards the top so this should work fine
I did say somebody say well Andre was
saying they'd still play solitaire
windows 2 came with it but candy crush
soda saga is taking its place I think I
think I'd honestly prefer playing candy
crush at this point but this is a great
academic exercise I don't necessarily
found myself playing or wanting to play
solitaire too much candy crush yeah not
so much I did play it when I first came
out we actually teach it in the games
course that I teach you know pick your
poison
they're all good it's all good stuff
exercise your brain however you see fit
let's go ahead and say local we're going
to store variable we're going to say
local why paws is going to be equal to
160 and leave it at that and then we're
going to say why pause is equal to why
pause plus padding here and then now
we're going to say oh we need to
calculate it here so why pause plus
padding times j minus 1 just like that
so if we do that and then we replace
this with y pause now that should oh
that actually had a even worse effect
okay that's not ideal
why oh because I need to do this I think
after after this is done is this the
case oh wait no no no I'm screwing that
up why pause equals padding times J
minus 1 I had that and right you don't
want to add white pause to itself oh
geez okay but we do need to we do need
to
[Music]
once so what we do what we need to do is
we need to say once 160 plus padding
times J minus 1 and so oh shoot
why is that not working ok plus padding
times J minus 1 why is this not working
interesting hmm let me see let me think
about this should make a stream on Ruby
I've been dying to learn it but I don't
know where to start
oh man I don't actually don't know Ruby
too well I would have to think about
maybe learning it and I can we can maybe
do a stream on in the future but more
likely would be maybe somebody else
knows the syntax I am NOT a hundred
percent sure I am not a hundred percent
sure myself oh wait ok padding times
that's what it is right ok because we're
multiplying it by so we're basically
calculating padding we're still doing
the same problem that we had before we
just need to add padding just just
padding that's it and
and actually we'll do it afterwards like
this and now oh that's terrible
okay wait patting oh right
white paw white paws pose back there we
go cool here we go that was painful I
apologize I often have slight issues and
this is a lot of sort of like the sort
of like futzing that goes on with game
development in some aspects of like
positioning things algorithmically it
can get a little bit odd get better
without it over time
certainly it's possible to futz your way
through anything but that was slightly
painful but we know we managed to make
it work everything looks great
yeah y plus plus padding yeah that was
the the problem that I had that I was
not seeing but now the good news is now
when we shift to the next card it
doesn't shift after a face back card
down the size that it would normally do
for a face-up card right which is nice
and I think if we were to take this out
the padding should still be preserved in
the right way yes indeed it is so cool
that works great we have everything
rendering in the right way I don't care
for this Queen of Hearts that is still
excuse me in my game so I'm going to get
rid of that let's go back to main which
is over here so the Queen of Hearts
getting rid of that gonna get rid of
that and let's get rid of the actual
declaration of it here cool things are
starting to look pretty good I would say
um I'm a fan and everyone kindly is
helping me out
Celie Oh 13 w old sorrow CS thank you
very much and that Andre is saying for
those who aren't too familiar in
Napoleon apparently came up with a bunch
of variants of solitaire while exiled to
st. Helena that's interesting I am if
Napoleon Bonaparte had candy crush he'd
never have escaped Elba and I mean who
would want to at that point right okay
so we have our piles everything is
rendering great everything looks awesome
another piece that we need to have is
the deck and the
that goes at the very top right this is
pretty easy though and really we don't
even need to necessarily do anything
fancy with the deck we could just
literally draw a face down card and that
would solve the same goal right so let's
say at this point draw I mean we don't
even need to be too fancy with it I'll
just say love dog graphics dog draw G
textures card back at 490 50 and if I
got that right we do indeed now have
sort of a visualization of the deck in
its right place in the stock and it's
not interactive at this point in time
it's not actually a deck we're just
simulating providing the illusion of a
deck being there but you know it solves
its it solves its purpose so the next
stage really is we need to start being
able to click and drag cards around not
just one given card but any card on our
game board and we also need to preserve
the child parent relationships between
cards that are on top of each other and
we need to actually start creating those
relationships because currently there
are no relationships that take place now
the good news is the the game board
starts off in such a way that we don't
need to worry about the relationships
from the get-go we just create their
relationships as we build cards on top
of each other and this actually makes it
kind of easy and nice but the first
thing that we'll worry about is being
able to take any of these cards and
click and drag them one at a time and
we'll see if we don't run into any weird
bugs along the way I'm sure we will but
what we can do is in game board we
should define an update function and
this update function will be where we
actually check for mouse input right
just like we did for the what was it in
card the card class I think is where we
had it I'm not entirely sure oh and also
a game board render
have things oh I guess yeah I guess I
can take this function and just render
just set it in here actually what I was
gonna do is to create a separate
function and this is good practice so
game board render tableaus and let's go
ahead and paste that just like that and
actually call it self render tableaus so
now in the render function not only
doing render the background first but we
also render the tableaus we have them in
separate functions so this kind of
maintains the grid and this maintains
the tableaus themselves the logic so
everything is a little bit more modular
makes a little bit more sense yeah let's
go ahead and implement the update
function so a function game board update
Delta time so what we want to do is
basically basically just iterate through
every single card that's not hidden well
every card that's not hidden we can
click and drag in every card that's
hidden in the top level of a tableau we
can right click to reveal so let's do
that
that sounds fine let's go ahead and say
it er ate through all visible cards
allowing mouse input so for
well say for I is equal to one until the
number of tableaus because remember all
of our cards are stored in our tableaus
so this is this is where we're going to
need to iterate to actually provide
input so we're gonna access the cards
each card we're going to check for input
I can actually say in our car class I
think we delegated some of this to it
right so this is yeah exactly so in car
update Delta time so the card function
itself remember it has an update
function where it does this so we can
delegate to our card class for this but
we want to do it only when the card is
we want to only allow this input when
the card is not hidden with this mouse
input equal to one so what I can do is
say if love that Mouse thought was
button pressed one and so and not self
dot hidden then allowed me to click and
drag the card around right so that's the
change we need to make the card to make
this work and then back in game board I
can say and remember these are all
stored as a table of tables so I can say
for J is equal to one until the number
of self tableaus at I do self dot
tableaus at i @ j :
update Delta time and if everything went
according to plan I should be able to
now click and drag cards and
unfortunately I can't because we're not
actually calling game board update from
anywhere and that's something that we
need to do so let's go to main Lua which
I believe is where we're doing all of
this and in update so we're drawing the
game board but as you can see we're not
actually updating the game board so
let's do that let's go game board update
Delta time render it click and oops
attempt to compare nil with a number
okay
card 22 which i think is probably what
we just affected oh okay we are not
actually passing an
and a why oh right yeah they're not
being assigned an x and a y okay so what
we can do is manually set them currently
what we're doing is we're sort of on the
fly calculating their position by
iterating through all of the tableaus
but what we can do instead is pre
allocate these x and y values and then
just render them flat out in the
gameboard class rather than having to
every frame figure out which x and y
they should be given to right King 440
dear streamer did you work with the time
series data I'm not not sure what you
mean by that do you mind clarifying and
virtuosa seven thanks for joining and
direct ian thank you very much for the
follow I think we're in a better
position if we allocate the X Y up front
I think that makes more sense so
yeah why don't we do that so rather than
in our game rather than here where we're
you know we figured out the why pause
and then we add 10 or 30 depending on
whether it's hidden or whatnot let's
just do this in advance when we actually
create the cards we can easily just
shift all of the this rendering lot this
sort of positional logic back up to our
constructor right so I can do something
like this I can say low goal why pause
is equal to 160 actually that goes over
here why pause is equal to 160 and then
get rid of that and then I can say local
padding is there right that goes inside
the actual J loop which is right here so
we're figuring out the padding in
advance and then this render bit right
here is what we care about so this isn't
going to be the actual the exposition is
fine do you want to store that well yeah
we can that'll be just assigned to X to
an exposition and actually this allows
us to just get rid of that altogether
because they're gonna be storing their
their value right just like that so
actually we'll be able to it'll just
look like this when we're finished with
it and then up here we want to say local
expose is equal to this value and we're
going to in the constructor where's the
card constructor right so we're doing
self dot deck draw so we're gonna do
instead is say local new card is equal
to self Dec draw new card dot X is going
to be equal to
X pause and new card wise name equal to
y pause and then we want to set Y pause
- we ended up adding to it the padding
value so which was here why pause equals
y pause plus padding right and now if
I'm correct this should still work
maybe not game board line 25 which is
there was a nil oh right
local padding is gonna be equal to oh
yeah yeah this is not going to work here
oh right okay this does complicate it a
little bit because now we are we don't
have this hidden value that we've pre
calculated that we can then tweak but we
instead want to do is what makes the
most sense we can oh well we can just do
this we can say
well okay padding is gonna be equal I
mean we could put it here but this won't
work because we need to specify the very
first cards padding no we don't because
padding is going to be set to zero by
default but that won't matter because
padding gets assigned here
so if we say local padding is equal to
zero and then we say X Y sorry I just
thinking aloud just want to refactoring
the code sort of live to fit the other
use case so we're putting this all sort
of up front so everything is I think
okay
yeah I think that this should work let
me just make sure I'm not missing any
nil references new car D that's not a
thing
game board line 28 which is new car dot
Y card from deck on line 24 wait hold on
temp to index local card from deck and
nil value interests staying wise why is
that broken of all things that is weird
unless we drew all 52 cards do I have a
weird loop in here that's drawing all 52
cards
this is interesting
why okay wait attempt to index local
card from deck card from deck what that
wasn't even a part of the equation
earlier that doesn't even make sense
the only instinct that I have is that
for some reason we're drawing more than
52 cards but oh we are shoot that's what
we're doing yep we are
I was calling self detect draw twice in
the same block that was my my fault and
now we don't have any cards okay so the
padding isn't necessarily working here
okay
that's strange oh wait is expose what's
expose being set to I minus one yeah
that should be correct right and then
the X pause oh but we are are we doing X
pause plus padding yeah we are or why
pause plus padding so we have a new
we're getting a new card we're getting
it from the deck we're assigning it an
explicit X Y now up front this is the
problem that we were running into before
we weren't assigning it in X Y so when
we tried to render it it wasn't working
and actually in card Lua are we
referencing self-thought X in here no or
not we're passing it an explicit X Y we
probably want self dot X and self dot Y
here which might be part of the problem
yeah that's what it was we were we
weren't referencing self dot X and self
that way we were referencing hard-coded
X Y that we weren't passing in and so it
was assuming zero because no is
effectively zero but now I can move six
around which is pretty cool and I can
move seven around and eight and five and
six so things are definitely progressing
so apologize for the hiccup there but we
have moved beyond having a static board
and now we do have an interactive board
and it's only the active cards so if I
try to click on this card for example
because it's hidden it's not actually
letting me click on it it's not it's not
interactive if it's hidden what I want
to be able to do is right-click it and
flip it over and once its flipped over I
want to be able to then move it around
because when it's hidden I'll then have
that ability it'll call update on the
card hidden will be true then mouse dot
clicked one will end up actually doing
something so why don't we implement that
which should be pretty easy thing to
implement actually if we're already up
here where love that mouse that was
button pressed one knots off that hidden
I can say else if and actually one word
because if you do it as two words it's a
subtle bug where I thinks you're in a
new scope and then it'll expect another
end and it just causes problems just use
else--if if you want it to be a line on
the same
the same left axis here I can say if
love mouse that was button pressed to
which is right click and self dot hidden
then self that hidden equals false so I
can do that I can do that I'm left
clicking if I if I click this left click
nothing happens but if I right click it
the problem is that right now all of the
cars register that right click on the
same frame so everything gets unclick
what I want to do is check to see
whether I'm in the right zone and that's
what I need to do right here so I need
to just copy that right on over tab that
over the tabbing is also bugged tab that
and then this is all good so rather than
saying self dot picked up is not self
not picked up I'm just gonna say self
dot hidden is equal to false now if I
click that car it's fine if I click this
card it moves if I left click a bunch of
time something happens but if I right
click notice that it becomes hidden and
none of the other cards become hidden so
this is great we've isolated the ability
to take cards from any area now I can
click and drag this card to my heart's
content because it's not hidden anymore
so it's therefore manipulable however if
I right click this Jack as expected both
of the cards under the Jack they became
visible and that is not behavior that we
want that is broken behavior it is
basically checking every single card in
the stack and basically and that's not
it's not what we want we only want to
check right click on the topmost hidden
card and only if it's the topmost card
of the stack not if it's a stack the
topmost hidden card underneath a visible
card we don't want it to be interactive
at all
so what we can do is rather than update
every single card we can just update
every single hidden card that's at the
surface level of the stack so if I go
over to game board and instead of
updating every single card what I can
instead do is say and I believe luma
does have a break so I can just break
out of it if I detect that
[Applause]
what I want to do is I want to determine
first of all that I've found a card
that's not hidden so if I say local car
card not hidden equals false right and
so what first thing I can do is I can
say if self dot tableaus at I J dot
hidden rather if not self dot tableaus
at IJ is hidden then I can say card not
hidden is equal to true right we found a
card what I should do rather I say found
card not hidden and I can update this
variable to say found card not hidden to
be true so check if we found a visible
card abort
checking for hidden cards later in the
loop so what this is basically gonna do
and my little it looks like my mixer
program thing we just got a brand new
sweet mixer and as this iPad program
that goes with it but I think this iPad
is on a automatic turn off or whatnot so
I had to reconnect it but in any case
basically what I want to do is I want to
say have I found a visible card if I
have I don't want to check any of the
cards underneath right so what I can say
is else else if whoops rather else if
found card not hidden
then break right because if I if I found
a card that's not hidden I want to break
out of this loop I don't want to update
it I want to I want to immediately end
this loop and not worry about it
and this will work for all of the hidden
cards below a visible card it won't
update them so I can test this I can I
can go over here I can click this card I
can right click okay that works
unfortunately okay not as expected
except my logic is wrong let's see if
not soft tableaus I J dot hidden then
found oh you know why because we're
going in reverse order that will cause
issues okay that complicates our
algorithm slightly so the algorithm
actually works from bottom up the
iteration of our of our cards however we
want to update them in reverse order we
want to draw them in backwards order
update them in reverse order
shoot that's actually not hard no we'll
just oh yeah updating them in reverse
order is fine as I'm going to keep
drawing them in the right order so what
I can do is I can say for AI is numb
tableau up rather this doesn't matter I
can keep this going left to right but I
can say for J is equal to a number of
self dot tableaus I until one with a
step of negative one so I'm actually
working backwards through the tableau
from the from the from the very top
level down checking for the logic there
now if I do this if I'm not mistaken I
can't right-click anymore it's not
letting me right-click to reveal any of
the cards that are in that table however
I can left-click to reveal a card if I
right-click here it still won't work it
looks like which is interesting but
that's okay
I'm trying to think is the logic such
that it would account for the top card
at this moment in time I'm not a hundred
percent sure yet I feel like it should
have at least revealed the top card
right
my mistaken to move the ace right click
no I mean we have the behavior we want
which is that we can't right-click
underneath the top card and have them
all get revealed but it's not revealing
even the top card so let's see
[Music]
so we're saying if okay we're going
through the toe wait because we're
moving oh right right right right right
right
we are still manipulating the tap it's
not taken off of the tableau that's the
thing the card isn't being removed from
the tableau it is still part of the
tableau it's just not visible it's not
visibly stacked on the same pile that's
the problem we still have this tableau
data structure we're just we've just
separated the rendering but we haven't
actually separated the data structure we
haven't taken that top card and
allocated it to a different tableau
that's what we need to fundamentally do
it for this algorithm to work backwards
so do we want to implement this yet or
good I feel like if we were to implement
the rendering correctly with the not
taking the cards out of the tableau this
would have fundamentally actually set us
backwards so yes a rule CS the visible
card still in the tableau that's correct
yeah
the next logical step is implementing it
such that by clicking a card off of the
tableau it removes it from the tableau
and maybe allocates it to another data
structure well
this is a tricky thing too because the
card if we update if we do all the
update logic from within our card class
the card doesn't maintain a reference to
his tableau should it maintain a
reference to his tableau I'm always a
little uneasy about sort of putting like
having all your objects sort of have a
reference to all your other objects
everything is just kind of this net and
it feels a little bit anti proper
object-oriented programming design it's
something that's hard to escape with
games because so many things rely so
intimately on having this update render
relationship so many things have so many
things need to talk to each other to
interact and to get to get information
and to render things correctly it's hard
thing to completely solve one thing we
could do is sort of have like a self dot
we would have like a self dot like table
our table pool I guess and this would
just be like a general-purpose tableau
just as we just so we demonstrate the
ability to right-click new cards and
move them around to other places and so
this table pool will be kind of a
catch-all I guess so let me think
we could allocate it we could we could
program it such that when you click when
you reveal so we could have it well
because if we're testing it within the
card class we need a reference to the
tableaus which are in the gameboard
class hmm this is where it gets a little
messy sometimes but let's figure this
out so and welcome to programming from
scratch those are the kinds of things
the kind of situations we run into
sometimes live engineering but I want to
click on a card we can just go straight
to implementing it such that we can't
program or we can't sorry we can't move
cards unless we move them to a another
tableau but there's the thing then we
need to keep track of whether they're in
a movement state that they're in a
movement state but actually no we
already doing that with picked up which
is fine but we need to sort of have a
central picked up so we can only pick up
one thing at a time and that's going to
be either well actually well if we are
maintaining that parent-child
relationship it's not a big deal so
first place to start is well there are
multiple places we could start I don't
like the idea of us programming it such
that we can just move cards willy-nilly
right off the bat and engineer around
that because it's not even part of the
game that would be more for testing
purposes and we're not really concerned
about that I don't think so I think what
we should do and this is the harder part
is go in towards a moving cards between
piles system and we can even begin to
enforce that cards follow the right the
right sort of conditions for being put
into a new pile so yeah let's do
something like that
now the only thing that complicates that
again like I said is the cards are
maintaining reference to their to their
input basically and so I'm almost
inclined to say we shift the input to
the game board for the cards and then
that way we can only maintain a we only
need to maintain a reference to moving
one card at a time and then if we update
all the cards all the cards essentially
what all their update is gonna look like
is gonna be something like this it's
gonna be
it's going to be self dot X is equal to
parent dot X and self dot y is equal to
parent dot Y update card based on its
parent and thank you very much
on any mesh sing for the follow and
emotive num a motive non amazon thank
you very much for the follow
that's a some tricky names this is
effectively going to be the end goal for
our card update function and well it
might be more complicated than that it
might ended up being something of the
form if self dot picked up then self
thought X is equal to the parent dot X
so if that Y is you will depend on Y and
what this is gonna do this this
therefore is going to it's gonna
propagate picked up to all of the
children of a given of a given card and
we're gonna probably have some sort of
very simple recursive function that does
this so we'll say something like
function card pick up and we're going to
say if self dot and so actually it makes
sense then to have a reference to all
the children so it does make sense to
have child reference so we say if self
dot child then well first of all we
would do is we say self dot picked up is
equal to true right pick gonna pick up
the card want to maintain that state and
then we're gonna say if self dot child
which means we have a child which means
this needs to therefore be a thing if
self dot child is equal to nil then we
want to essentially call self dot child
pick up right and so this will just
recursively go down until we reach the
end of the cards that have no more
children
this this seems sound to me and then
there's going to be two parts to this
it's gonna say if self dot picked up
then and then here's where we're gonna
say basically if self dot parent is
equal to nil then right because if it
has no parent we're basically it's gonna
follow the mouse so we're going to say
[Music]
we're going to say basically this
actually yeah we're just gonna do this
copy this over here like that so
basically if we're picked up but we
don't have a parent that means we're the
card that we're clicking and dragging
around that's the parent level card so
if we're picking up an entire stack of
cards that's the bottom card and all of
the children are on top of it and so
what we're going to do is we're going to
say if we're picked up but we don't have
a parent we're you're gonna move us
around the mouse cursor but else else
will mean that we do have a parent and
thank you very much 2news gang if we do
have a parent then we're just going to
set our self dot X equal to our paradox
whoops and our parent dot y RR y equal
to our parent dot y plus we'll say plus
30 right so that way we get a stacking
effect when we move our cards around so
this will preserve the distance between
all of the cards but the parent will be
at the top level and that will follow
our mouse around so we can therefore
move a whole stack of cards and click
and drag them as we see fit
then another important thing that we
need to do is say and we'll have a
function for place down and place down
is gonna be a little bit trickier
because this is where we're going to
need to actually we're going to need to
know where to put it in the right
tableau excuse me
whether it's a tableau whether it's a
whether it's one of the top decks well
one of the other these are important
things to take into consideration and
I'm even wondering whether we should
have a tableau class maybe not at this
point it might be more engineering how
so than it's worth but when we place the
card down we effectively need to well
basically what we'll do is we'll say if
self dot parent is equal to nil then
well actually this is more complicated
than that these these cards are actually
going to be shifted around if we take if
we take as input and this is a more
functional way to think about this if we
take as input a game board right we
assume that we're going to just get the
game board as an argument to our
function for placing the card down this
is sort of how you get around objects
having references to other objects our
fields that are other objects you pass
in what you need as arguments to your
function so in this case I can say card
place down a game board game board I'm
going to actually pass into the
functions that are just having game
board reference in each card right so we
don't necessarily need to have a game
board reference stored for each card
we'll just you you will just get a
reference to what we need it when we
care about it well we'll pass it into
the function for place in the card down
so if the self thought parent is equal
to nil so this is where we get into the
or rather this is where we should say if
self that child is equal to no and in in
this particular instance we can check to
see if placing in tableau or winning
pile else we want to check to see if
placing in oh actually we're only gonna
care about whether a parent is equal to
no we're not gonna worry about every
child card getting place down because
that'll just get too complicated all the
cards are gonna check at the same time
for whether they should get placed
somewhere we're just gonna check whether
our child is know or whether our parent
is know so whether we're a card that's
by itself or well actually and to be
fair it needs to be if so if that child
is equal to nil and self that parent is
equal to know is that the case yes
so if self that child is equal to no and
self that parent is equal to nil so this
is a card by itself this is important so
this is where we're going to check
whoops check to see if placing in the
tableau or the winning pile this is
where we can place a single card by
itself else if self dot child is equal
to nil and self dot parent or rather if
self dot child is not equal to nil and
self dot parent is equal to no then what
this is gonna do
otherwise only worry about placing a top
level card we're gonna check to see
whether we have some children some child
but no parents and this will mean that
where it will effectively refer to a
card that we've clicked that has cards
stacked on top of it that is a parent
card with that is a that is a parent
card with children it does not have any
parents itself therefore we only are
worried about just it and placing all of
its children therefore with it onto
another tableau pile and so I apologize
if I'm losing anybody news King Wow
David Malan looks a lot younger I don't
claim to be David Malin but if anybody
has any questions about the logic that
I'm going through here definitely let me
know because I realized that the
mechanics of this might be getting a
little complicated and it sort of is a
little bit complicated this might be one
of the media projects we've worked on
and if I'm going too fast I apologize
trying to hopefully get in as much as I
can before for today but this will
continue in a future part of course if
we don't finish we're probably not going
to finish today I did sort of in my head
plan at least three streams for this but
let me know if you're if you have any
hang-ups or any questions so far and
what we've talked about because I
realize we're moving very quickly but we
are checking just these two conditions
these two very specific cases of whether
our card is by itself we can check the
tableau or the tableau the winning piles
over the tableau and then we want to
check whether we are a top-level card
with children and we're gonna place that
down only in tableau is not in not in
winning piles place only in tableaus not
winning piles core so apologize for the
complexity it is a relatively complex
set of conditions that were checking for
maybe not maybe I'm overthinking it but
there is a bit of a bit of work we have
to do to get this to work well now the
game board since we're passing it in as
a function
our into our function as a parameter we
can start to use it to get the
information for the tableaus and the
winning piles that we care about so we
can reference those bits of information
here in card place down because we're
passing game board in to our function
now I don't know if I'm necessarily
ready if we're necessarily ready to do
that let's just make sure this actually
still runs which it does I can move this
card around and if I do that I can try
to place that card down now what that
and having the effect of doing it would
first of all it didn't work one of the
other things that we should probably
take into consideration is if we click
on another card
we shouldn't pick up the card
we shouldn't pick up another card
because then we essentially kind of need
a global sort of card as being picked up
state to allow us to know when we can
pick up a card right I think we do I
think we I think we really do need this
so what I'll do is I'll make a new field
I'll say self dot picked up card or card
picked up we're gonna set that to false
first off and then in card class itself
I think that's where we're actually
identifying whether that card is picked
up and now we have a card picked up game
board field and a card picked up per
card field and this is sort of
complicated because there are cars
multiple cards that can get picked up
but we want to also preserve the fact
that we're picking up a cards that we
don't pick up other cards when we left
click or when we set a card down so
let's maybe pass into card update a we
can pass on our game board to card here
as well at this point it's almost like
why not just have a game board reference
in every card at this point but we'll
try to keep it as lightweight and non I
forget the term but there's there's a
term for it for having sort of
references of everything altogether it's
just bad practice so what we'll do is
we'll pass in game board in this case to
the card to the cards update function
and here we can check to see whether we
are picking up a card and you can do
that down here
[Music]
so we're toggling the states currently
so this is where we're going to need to
get a little bit more logic I basically
need to say ensure we're not already
picking up a card so I can say if game
board dot rather if not game board dot
card picked up then this indentation is
killing me a little bit that's okay
there we go then we can toggle we can
toggle whether it's picked up or not if
we're not already picking up a card
actually is that even correct because at
this point
[Music]
we can say if not game board card picked
up then self-taught picked up is not
self dot picked up this is a toggle but
we don't want a toggle for every card at
this point we just want to check to see
whether we're not picking up a card
currently and so then we can say self
dot picked up is equal to true and game
board card picked up is equal to true
then we can say else if self dot picked
up then self dot picked up is equal to
false and game board dot card picked up
is equal to false so it's a more
complicated toggle let's see if this
works
62 are we not passing in game board we
are right where that where's that called
from that was card from card 62
oh we're not passing it into the card
function right let's do that
so in our update function we're going to
go down to we're updating every card
which is right here and we're gonna pass
in self because we are we are self is
the game board in this context now let's
try this I have my card if I click this
now notice that I clicked on the card
below and I can only pick up one card at
a time but due to the fact that the
tableaus are all oddly sort of stacked
and layered now we get some interesting
artifacts right now we can realize that
these cards when we pick them up they
need to have a different rendering order
actually so this is a little bit more
complicated than we originally might
have thought which is okay this sort of
thing happens now this this one on the
right for example is above all of these
because it gets drawn last remember
we're drawing all the cards from each
tableau left to right so we're drawing
this for first so it's actually going
underneath all of these cards right
so if I click and drag this around now
it is getting drawn it's still getting
drawn first it still thinks that it's
right basically in this tableau the way
that we've structured the data right so
the card that we're currently picked
that we're picking up one we should
probably get rid of it from the tableau
that it's in and then to defer the
rendering of it to a different place
outside of that nested loop we need to
have sort of a card that's currently
being picked up or a card stack that's
being picked up and this is okay trying
to think just moving the cards
themselves since they're references it
might end up duplicating the cards and
if we remove it it might actually end up
deleting it from the original deck our
original tableau altogether so it's a
little there's a few pieces here that
are a little bit messed up
the important thing is though that we
can only pick up one card at a time
thankfully it's a little bit buggy
currently but we don't really have to
worry about this too much because
eventually we're only gonna we're gonna
have a very restricted set of situations
in which we can pick up cards we won't
ever run into rendering bugs like this
well we won't run into render ordering
sorry won't run into pickup or during
issues like this everything is going to
be very well defined but we are going to
need to get there first we're going to
need to make a few changes to our logic
first among them being any card that we
pick up from a tableau needs to have
priority rendering over everything else
on our board which means that we need to
essentially take it out of the tableau
out of the data structure that it's in
probably cache where it was before so
that if we miss click it goes back to
its prior position that's an important
feature we should probably think about
or at least minimally not allow clicks
in the wrong positions and force that
the the user put is put in the right
position before
allow them to pick up another card or
another set of cards and then once we do
a click it and put it into the right
tableau it needs those cards need to go
into the right data structure we need to
make sure there are no extra copies of
cards being made and no cards are being
removed and deleted completely as in we
don't have references to cards whereby
when we remove a table or when we remove
a card reference it deletes all of it
but we remove a card from a table it
doesn't remove it and its references
there they're there for getting rid of
all the cards period we have a few
specific issues that we need to be
conscious of here and separately can we
make any moves here I don't doesn't look
like we can we need to also implement
the ability to draw cards from our stock
right we need to be able to click a card
here and get a new card here and we can
do this forever by the way up until the
car up until the deck is drawn and this
is where we're gonna need to change how
the deck is also rendered so as we can
tell this is a fairly meaty project I've
got a very sizeable set of problems to
solve but we can definitely solve all of
them let's first start by taking the
card from the tableau and shifting its
render priority why can't we have a
tableau position in a card says several
CS we could do something like that that
just gives us more stuff that we have to
manage rather than just being able to
click and drag stuff on top of other
things because once we click once we
click a card and we get it's a tableau
position it's not really super
meaningful to even have the information
I would necessarily say a lot of a lot
of this logic is kind of just inferred
in that particular case the ordering
kind of just helps us out we don't need
the numbering the explicit numbering in
that situation unless you want to
clarify what you what you mean more
specifically I don't but I don't think
having a in index necessarily associated
with each card will help us here I think
a lot of that I think the its position
sort of in the data structure itself is
the important factor
let's go ahead and when we when we end
up getting the card picked up from the
deck like I said we're going to need to
make it so that it gets taken out of the
data structure doesn't get removed but
maybe gets put into a temporary staging
area so what I can do is I can say in
game board maybe I'll have self dot
picked up cards is going to be equal to
a table and if it's a if I were just
picking up a single card this table will
just be one card large right doesn't
matter if we're picking up an entire set
of cards then this is important this the
the table will actually store every card
and we can then render them in the right
order based on their parenting so what
we're going to do is once we pick up a
card in and again this is in card da lua
then here we can actually using that
reference to the game board we can add
this card and all of its children to the
game board sort of that temporary
staging ground and then the important
thing that we can then do actually is
and these should be put in the right
order too so this will work if we just
add all of the children in the right
order so we take the parent and add all
the children sequentially we can then
render all of the cards sequentially and
that will have the correct effect so
let's go ahead and first in game board
let's write where we're gonna end up
rendering this which is gonna be here
underneath render tableaus we can say
self render picked up cards and let's
write the function game board render
picked up cards and by the way there are
million ways that you could do this this
just happens to
the one way that I'm constructing again
purse arul and other folks definitely if
you have ideas or questions ask them
provide them and we can make this more
of a collaborative effort but this is me
at this point just kind of figuring
things out as we go the way I think
about solving the problems very open to
other people's ideas so what we're going
to do is we're going to say for I is
equal to 1 up until the number of self
picked up cards do love art rather and
if we're updating the position of the
cards then this should be fine actually
because they're gonna have the picked up
flag associated with them right so we
can then just do self dot picked up
cards I render and this should actually
work I say that but I feel like I've
gotten that wrong several times already
so in my mind I'll say that that should
work but well we'll soon see whether
that will indeed work those self dot
picked up cards should all have the
picked up flag set to true on them the
this flag right up here which again
we're checking for in our update and
remember if they are picked up they will
look to see whether they have any parent
cards if they have parent cards they
will get the XY of their parent and then
shift their rendering position down by
10 pixels and we will set the if it is
the parent remember it will itself get
assigned the mouse position so that
should work now if we the question that
we then run into is once we pick up all
the cards once you render them in a
different
Oh another thing we have to also
consider what you just realized we need
to actually remove those cards from the
tableau they were just in right because
they'll be in two places at once they'll
be rendered in two places at once
at this point I think we can demonstrate
this this maybe not
let's see game board render picked up
cards oh because we aren't adding them
to picked up cards yet I don't think are
we no I don't think we I don't think
we're adding them to picked up cards yet
so that's another thing that we're going
to have to do if you go to over here we
can say
what we actually need to do I just
realized we created that pickup function
which is a recursive function recall
which propagated the picked up flag to
all of its children so what we can say
is if self dot parent is equal to nil
then self pickup and I believe what this
will do is just remember set picked up
to true right which is here but then
it'll also propagate it to its children
and right now we're aren't establishing
any parent-child relationship so that's
going to be one of the next parts of the
stream we're going to need to do that in
order for things to work the way we want
them to and then we can say this here
like that so game board card picked up
is to true and another thing that we're
gonna need to do is when a card is on
the tableau and it's below other cards
we can't really click on well hmm we
have to restrict our window which we can
click the cards cuz what normally you're
only allowed to do is click on for
example this green part here this would
be where I could click if that were
another card that was revealed I could
click that card but I could also click
this card so what we need to do is
actually do a reversal on the on the on
the tableau we need to check for a
collision in reverse order not in not in
front order because if we do it in front
if we do it from back to front order we
could end up actually picking up the
very back cards when we actually meant
to pick up the front cards right but
this is fairly easy to take care of we
can do this just by ensuring that were
and actually I think we're already doing
it in the right order
let's go to game board are we doing this
in the right order we are rendering we
are updating in reverse order correct
yes
so actually yeah wait no we're not yes
yes we are sorry I was looking at this
loop it's this loop that we care about
since we are actually in
first order from the back to the front
checking for clicks this will pick up
the back cards before it picks up the
front cards now the problem is that
there's overlap so what we actually need
to do is change our collision box for
the front card the back cards all week
we only want to worry about the top part
of them we only want to click on the
very top layer we don't want to do that
for for the very front card the very
front card should have a hit a collision
box that's the entire card collision
boxes in where the mouse is being
checked for collision wise so that'll be
and that will be the sorry that'll be in
card that will be he where where is it
it is here essentially this this bit of
code rather than checking for card width
and card height we're going to check to
see whether it has any children if it
has no children then yes we can we can
check its entire collision box its
entire card width and height but if it
has children we need to check only the
very top 30 pixels right that because
that's the number of pixels that were
offsetting it by 30 so we'll check that
which we can do here we can say if self
dot child is equal to nil then which it
should be then we'll do all of this
didn't mean to do that
well actually what we'll end up doing
what we'll say is ok here's what we'll
do
rather than duplicate our loop we're
going to confine Y bounds checking based
on parenting smaller hitbox for when
cards are behind other cards so if self
dot child is equal to nil we'll say
we'll do a local y Y check or I guess Y
bounds is going to be equal to card
height right we'll set this to Y bounds
and then if self that child is equal to
nil or not equal to nil we'll assume
that we can check the card height but if
it has a child if this card has a child
what I'll end up doing instead is set Y
bounds equal to 30 and what this is
going to do is depending on whether it
has children or not it's gonna either
check the top 30 pixels or the entire
card right that's what this helps us get
the right click the right card get the
right you know the right specific card
that we care about if we're clicking on
the top edge of a card
we only want that particular specific
card well actually is that even going to
work
[Music]
actually I'm just realizing now I think
in that case we have to check for
collisions going front to back oh wait
no that's that's not necessarily true
now if we click on this right yeah
because the back card is only going to
check these top 30 pixels so if I click
here yeah it won't trigger a collision
correct okay so everything is sound I'm
not going insane at least I don't think
I am fingers crossed so that's that's
working let's test it make sure we can
actually still pick things up yes we can
pick things up yes we can things so I'm
still don't render correctly but that's
okay we're going to fix that we're going
to set in game board well we're going to
we're actually back to the card class
where we actually set things to being
picked up self dot pick up we're gonna
do that so game board card picked up is
equal to true and then we want to end up
actually removing the card from the
right tableau hey as it going we have a
very special guest today yeah sure
here's a view of what's going on so
everybody in the chat shows us the David
so we're currently implementing
solitaire doing a little bit of some
nitty-gritty stuff but here's what we
have going so far this is like the
longest implementation of solitaire I
think I've ever seen oh yeah day six
yeah it feels like day six now we have
we have cards moving around today and we
have the piles of stuff but currently
implementing it such that as you can see
for example if we pick up card number
three because these are all being
rendered left to right you can probably
guess what's gonna happen this card
actually gets rendered below all of
these cards so when a card is in a in a
state of being shifted around what it
actually needs to happen is a separate
rendering order needs to be creating no
so that's kind of like an CSS z-index
familiar yeah what we're doing in this
case is more hackish because because
because we know we have a very limited
set of operations we can apply this card
if we're we can only move one card or
card pile at a time so if we're if you
want to move for example any card at
once we can just shift it to a different
rendering order altogether which would
be kind of like a Z order but it's
essentially just getting allocated to a
different table I got something
focusing hello as well well this is kind
of like than Photoshop and keynote and
PowerPoint where there's this notion of
a vertical axis like yeah with objects
on top of other exactly what does it
bring to front or send you back yeah so
this cart for example will render on top
of this one because this came this one
came from the fourth set of cards this
one came from the third set exactly
taking off shortly well can I just say
hello to Andre here and seracs
and Bella and oh I look a lot younger
than kolten that's good
this is my clothes they wrote that
earlier because I think they were saying
I maybe I sounded like you or something
oh that was pretty good I don't want to
drugs I just wanted to say hello I'll
hop back on the chat but really good to
see everyone thank you for tuning in as
always and can't wait to see the game we
played ultimately cool awesome thanks so
much for popping by I appreciate it
so yeah that's we were in the process
then of establishing that secondary sort
of rendering location hello we had any
good to see you
I mean Adam and Cowabunga and as Leigh
and everybody who's saying hello it's
been a little bit lighter of a chat
today I'm guessing that might be because
it's a little bit more nitty gritty and
maybe I'm going a little bit fast
speaking to that I needed a little bit
of a mouthful lubrication but
essentially the next part of this puzzle
that we're solving is getting the card
from the table sort of figuring out
which table it's in from Boston Mass I
just finished my Snapple it's very
appropriate cuz we are very close to
Boston actually getting the card from
the right table and putting it into a
separate location now this is a little
bit tricky just because again we don't
have a reference to each individual
tableau within the card itself and this
might be where we have to start thinking
okay do we in fact need to store whether
a card is in any given tableau so that
we can get rid of that card from its
data structure so we can sort of take it
out temporarily and maybe we put it in
later and we
to the doctor saying ETA on the next
code review good question I think
probably next week is what it's looking
like for the next code review the
unfortunately it's a bit of a busy week
for folks unfortunately David and Brian
both have conflicts and are unable to
come but I would expect one either next
week or the week after and we'll update
the schedule to reflect as much and
we'll talk about what might be the most
ideal but we do enjoy the the code
reviews those are a lot of fun so yeah
I'm realizing here that the tableaus the
fact that we don't have a reference to
it in the card and that's where we're
doing the update to sort of you know
bring it out it's causing a slight
problem although although although we're
checking we're doing the actual from
within the game board we are looking
through the tableau to see or to
actually update sorry rather to update
the card class or the card object we are
going in our game board class through
each tableau and therefore getting a
reference to them it's worth maybe I
could just pass in self dot tableaus I
there right so the card takes a tableau
as an argument to its update function
and as a result now we do have the
ability to sort of piece out the card
and also therefore its children if
that's what we need to do and then this
will help us you know restore the
rendering order so I think that's why I
won't might end up being what we
actually do so let's go ahead in
here we have self dot pick up
the problem is the recursion of the
pickup because when we pick up just this
top card I guess we could just trigger
the tab below I guess we could trigger
we can just call table dot remove
actually and that would work yeah we
could do that okay that's what we'll do
we'll just say pickup also gets the
tableau and what we'll do is we'll say
pickup here passing in the tableau which
we passed into our update function so
things are a little bit you know are you
were passing a lot of arguments back and
forth but at least we're not maintaining
too many sort of object references which
is arguably better we can then in our
pickup function actually maintain this
removal of the card from the tableau
I'll say tableau dart sorry table dot
remove tableau and actually what this
does if we just call it as is it'll just
remove the card from the tableau so we
can do that and then this will call that
this exact same bit of code will execute
for all of its children as well
okay so then if I click this as expected
it deletes the card because this is was
one of the worries that I had before and
that is that when you table dot remove
it's just removing it from the table
altogether and getting rid of that
information what we want to do really is
copy it to the game boards temporary
staging area which is what we can do
exactly and so we'll pass in the game
board here so let's write a function
here just because this this function is
getting a little bit complicated so what
we'll do is pick up the card flagging it
as such then remove it from the game
from the tableau in which it is make a
copy of this card and add it to the game
boards staging hand and the staging hand
is just where where we can move the card
around before we click it and actually
place it down somewhere concrete when we
do that it's going to essentially take
the staging area cards and then put them
into a tableau it's going to inject them
and as a result of that the staging
areas can just kind of be filled back
and forth with something different at
different times but Kappa Banga do you
think all of this would be easier to
code on something non Lua uh probably
not
honestly it's I mean yeah - Andres point
unity is unity is pretty good especially
for the debugging because so Kappa Banga
does have a good point debugging in Lua
isn't the best you can do this in
certain ie des I mean certain things are
kind of trickier to debug it depends it
really depends debugging is arguably not
great there are certain plugins that you
can get that will let you deep bug in
love 2d love 2d debugging
so there's this which lets you actually
run sort of a rebel a debugging rebel
which is kind of cool and there it's a
little bit convoluted and part of the
reason too is we would have a lot of
extra code and boilerplate and we need
to teach out all the stuff works but I
would say if you're interested in the
good debugging setup I would use Xero
brain studio which is an IDE that has
love 2d support because I've heard
excellent things and I've had several
students use the framework to good
success
I personally I'm not a huge fan of it I
would rather use printing and recursive
outputting of tables and stuff looking
at the memory looking at what's going on
that resounds better with me personally
in the context of unity I'm a big fan of
unities debugging but even in unity I
still use echoing a lot for debugging
because sometimes just all you need to
do is you need to look at the right
value and make sure the right value is
getting set but different people have
different mileage there are really cool
integrated debugging tools in love 2d so
for example a glove too deep debugging
console I saw this at some point and it
was a big fan I just had to figure out
which library it is it's a library me
see there's love Bert I have heard of
love bird which is a debugging console
for the web browser this is kind of cool
this is interesting it actually lets you
look at your entire stack of variables
but even still you're still seeing
functions and tables and stuff which
isn't necessarily all that interesting
so recursive outputting of these things
of less functions with more tables is I
think ultimately a really good way to
debug and that's what we did last time
machine util dot Lua if you look at that
we have a function called dump which
just dumps a table recursively and so if
you have complex data structures where
the data is getting manipulated in weird
ways then yeah you can use that and I
think that's an ideal way to go about
doing it and that resounds well with me
check out zero brain studio if you're
interested in a really good love 2d base
debugging tool though unity Plus Visual
Studio is really cool for debugging but
I'd argue its main strength is being a
strongly typed language yes that's
that's true and that was one of the
things that he brought up earlier was
whether you're in Python or Ruby or Lua
or some other dynamic language debugging
at compile time isn't the thing so you
don't have this
kind of safety net that Java and other
languages give you when you sort of
overlook or at least take for granted
until you get out into the dynamic
language space it's a trade-off that you
make for not having to put up front as
much effort to get things rolling fast
and also having to compile and run stuff
and that that sort of more rigid loop of
development it's different I I'm a big
fan of dynamic languages but there are
times where I do wish that I do have
that I did have compiled you know
functions and objects to at least sort
of say oh you know you can't be passing
this data this way or that's an old
reference you know blah blah blah should
probably fix that or you know or the
wrong type of data is getting passed
around you don't see that in a dynamic
language like Lua at all that's one of
the things that really helps when you're
using especially with polymorphic data
yeah that's something that you can
really get a bit of help with in a
context like c-sharp or Java but again
zero brain studio check that a big fan
of uh of that even though I don't use it
myself I think based on what I've seen
but what my students have used it it
looks really good okay so we have
currently removed the bit of information
that we care about have a Banga you're
welcome
we removed the card from the table but
we need to actually copy it and put it
into our into our staging area along
with all the children so and I'm
actually not sure if Lua makes this easy
to just move Lua move objects between
tables let me see
oh that's okay that's cool I've never
even tried to do that
the three arguments I'm not 100% sure
why there's three here okay oh I see new
being the new index table that remove
being the is that the right argument
Oh Lua 5.3 has tabled moved but I think
love 2d uses Lilith 5.2 love to deal Oh
aversion I'm not 100% sure actually
oh yeah Lua 5.2 I think I mean this was
a long time ago but I don't think
they've updated love zero point ten
point two Luo version Oh actually I'm
using Lua 11 I think
level 11 love 11 Lua version
[Music]
what's love got to do with it somebody
says love that yeah so it doesn't have
table move but it looked like we can
actually a table move in in Lua whoops
table move probably giving me references
to people moving physical tables not
what I want oh that's not what I want
table shift Lua rather move elements
here we go actually was this thread that
we were just looking at so table dot
insert which is what we've been using
takes in the table this new I'm not
remembering it's offhand but this is
development you know googling things
constantly is part of the struggle table
dot insert takes in okay so it takes in
the table the index and then the actual
value okay so we can do then okay that
makes things actually easier quite a bit
easier so we write because table dot
remove returns the value of course of
course and if you don't do anything with
the value obviously that will get you
know garbage collected like it did
earlier it'll get removed it won't be a
thing but no this is great so in our
game was a card yeah I was card so this
is this is what this is right here so we
gonna do table dot insert into the game
board Dot cards picked up was it card
picked up cards picked up cards whoops
we're gonna insert that and then we're
gonna remove
actually we're just gonna remove the
last thing from the tableau oh this is
wait no that's not the right order we
just want to remove always always gonna
be whatever's in the first index
actually so that's fine
so we'll just remove whatever is it at
index one and now if I'm not mistaken uh
index local game board card 27 Oh cuz
we're not calling it pickup we need to
actually pass in the game board which is
down here yep tableau and then game
board right is that correct
yep let's try that again so it's not
moving it around I mean it's it's it's
it's it's doing some weird stuff but
it's working it is shifting the it is
shifting the card to the staging area
and preserving its character in the fact
that it's a Queen of Hearts that part is
staying consistent which is great kappa
Banga asks wouldn't non version
dependent if you would define table that
move yourself and then use it anyway um
yeah that could work I guess I don't
know if we'll need to use it elsewhere
maybe if we need to use it in other
places we'll consider excuse me we'll
consider implementing tables that move
ourselves if we ever updated this code
base to a different version of Lua and
they used a different table move that
could cause problems so I'm a little
reluctant to do that if we know that
table dot move exists in the Lua
landscapes somewhere is my only my only
concern led 52 says just start the
season 50 course online take me four
hours to complete them Paria test okay
but that's good though 4 hours for your
very first time going to cs50 that's you
know that's faster than a lot of people
get it finished so good job on you what
we essentially did today was a graphical
version of Mario which is you know
different ballpark different beast but
you know same logic essentially nested
loops right getting the getting your
hands or getting your mind sort of
wrapped around nested loops in a very
comfortable way will serve you very well
let's go ahead and figure out first of
all what this weird behavior is so we're
clicking a card and then it immediately
is sort of getting shifted over now the
weird thing is that it seems to have
reordered these cards a little bit in a
strange way right
and then not only that but it also first
of all this isn't getting rendered
correctly I don't this is really weird
behavior so I don't know why for example
okay as well I can't even click this
anymore it doesn't keep it it doesn't
keep the the XY of the card being
updated oh because we're not updating
the card in we're not updating the
picked up cards I don't think I think
that's the problem
these need to be updated separately so
for I is equal to one until number of
self dot picked up cards stew
self dot picked up cards IJ update Delta
time self soft tab blows actually well
that doesn't need a reference to the
tableaus I don't think let's try this
game board 66 wait a second oh wait they
don't need IJ we just need wait we do
need I know cuz J is not a thing right
just I okay that should be fine we say
that and then I I'm always mistaken okay
so so if that picked up cards that did
not work they're not moving around so if
you go over to our card class let's look
at the update function once again and
let's see if self dot picked up
now self-thought parent should be nil
which means they should be aligned with
the mouse cursor
ha
[Music]
and oh wait
[Music]
could it be this
self-taught picked up his false and
gameboard dot card picked up is equal to
false oh wait is this
I don't have this in two places oh I do
have this in two places I'm not sure if
that affects it much at all no it
doesn't like it does it does move it
just keep moving the card well well the
problem now that we have is if we're if
we do have the game board being having a
card picked up we have to set it down
once we do have it picked up so and then
we need to read we need to get rid of
the cards in our table below and then we
need are in our picked up hand and add
them to the other tableau right and
actually so now we need to check for
there's a lot of pieces involved here so
now what we need to do is we need to add
them basically check how first of all
what we should do we should figure out
what the fact that it's not moving the
the cards around why it stops this is
normal it's trying to as trying to
remove a card from the tableau which
there's no cards anymore because it's a
we there's only one card here so as soon
as we then click there which is weird
actually because the tab what it's not
interacting with a car that's in the
tableau so I'm not totally sure how
that's happening but the one important
thing that's currently bugged is the
fact that we are not the cards not
moving around essentially
[Music]
I also apologize that we're not moving
terribly fast this is a little bit more
of a nitty-gritty stream so we're doing
a lot of sort of algorithms and
functions and stuff like that as opposed
to the more visual stuff I mean we did
get you know this all rendering and
whatnot
there's a long ways to go we'll probably
end up doing is before the next solitary
stream which we can't do this week we
actually have streams I'll set up and
maybe the week after is all come with
some of the pieces pre created just so
that it's not gonna dull too much time I
spend too many streams on solitaire
because otherwise we might need a few
more we might need more than three it's
looking like it's relatively complicated
but we'll see we'll see how it's we'll
see a little bit later logically is it
easier to click and drag this way you
could finish dealing with a card clicked
when you release the button before
another click happens not necessarily
ultimately I think it's the same amount
of logic because we should just be able
to set the card down as soon as we get
to the next click and we are not set to
picking up a card being equal to true
right or being equal to false let's
figure out let's figure out why we're
first of all why we're not moving around
so they clicked on the card the card got
the picked up flag right we're updating
the card every frame and we can actually
test this I think if we were to go into
for example the game board class and we
say Prince updating a card and then we
just run it we should get this frame we
should get this frame by frame right so
a CD desktop or rather where should
where are we CD dev streams I believe
solitaire and then we run this we should
get we should be getting Oh actually
interesting we're not getting anything
oh okay from 1 to 1 it will still work
right we are adding to self we are
adding to picked up cards right mine
might not mistaken
first of all okay let's do print number
self picked up cards see that first run
this Oh it's zero okay so we're not even
adding it to the table
okay fascinating well that's part of the
bug okay using echo debugging for the
win
we haven't actually put it in the right
table so this is where we normally do
that table dot insert game board picked
up cards
does it necessarily need to have a
number because if it does we could just
say number oh we could say let's see the
table dot insert
I see
so I think maybe it's getting confused
because maybe it's expecting well maybe
well no that shouldn't be the case right
we should be able to just call table dot
insert with our game board picked up
cards right we're inserting into a game
board picked up cards that's our table
of cards and then we are removing we're
getting or adding what we're removing
from the tableau at index one yes yes
and so why isn't that being transferred
over itself not picked up right okay
we are calling self dot pick up yep
apologies for the bug just want to
figure out what's going on
so gameboard dot picked up cards is
indeed the table that we care about it's
getting a size zero so it's not actually
getting the value and inserting it into
the into the into the table so hmm first
of all I don't need to be looking at
Main I'm not sure I'm looking at Main
Constance will look at card pickup right
oh wait oh wait no the tableau is fine
because that's the tableau that
yeah it's getting it stuff it's
basically a reference to itself it's
getting a reference to its tableau this
is a little bit of a weird way of doing
it but stuff that tableaus at I J update
and then we're we're actually calling
the everybody happens to see the bug if
I'm just missing something obvious
definitely let me know to me this seems
seems sound but is probably a silly bug
that I'm just missing here because we
are passing in the tableau and the game
board and those that's the right order
if I'm not mistaken yeah the tableau and
the game board right which is here self
dot picked up is equal to true
and then there they're definitely not
getting parents right so if that parent
is always gonna be nil when they first
get in San Shi ated right here and we're
not doing any explicit parent-child
pairing just yet so this is fine self
doc okay self : pickup tableau which is
tableau is getting passed in here yep
and then the game board is getting
passed in as well the game board card
picked up is equal to true I almost feel
like it has something to do with this
table we insert am I just getting this
order mixed up
let's make sure that table insert
actually takes in yeah I can take the
value do we have to as table that remove
table that remove is working it's not
returning the value am I getting this
mistaken insert it into a table the new
value and then wait a second oh that's
the position I mean we could specify the
position if we want to we could say
because I don't think this is strictly
necessary but table dot insert if we
just say number of gameboard dot picked
up cards plus one right that will just
be the end of it I don't see that fixing
the problem but yeah see that doesn't
fix the problem it doesn't matter shoot
okay
this is an odd odd bug I apologize this
is taking so long I'm gonna commit what
I have right now if anybody wants to if
anybody's interested in figuring out the
current bug and I hate the fact if it
weren't in such a rush you'd probably go
for another hour but unfortunately I
have to leave at 4:00 so we have 20
minutes to try and figure this out but
we'll do our best we'll say that this is
going to be currently currently buggy
card not adding to picked up cards oh
wait is it is it doing multiple click
handles / Oh
yes that is probably it that is probably
it so what's happening is it is up
dating the so it's updating all of the
cards in the its updating all of the
cards in the tableaus and on the same
frame directly after all of this happens
it's updating all of the cards in the
picked up staging area and on this frame
the same frame we're getting the left
click is equal to true and it's doing to
update calls for these staying to update
calls for this card and so what we need
to do is we actually need to bring this
up above we need to say update the
staging area update all the cards update
all cards in hand first and by ah shoot
that didn't fix it either damn I thought
I thought I found the problem okay shoot
really
that wasn't that that was definitely
like a issue the fact that we're calling
two updates on the same card in the same
in the same loop or the same function
body that's the that was a big cause of
the issue sir II was saying should it be
tabled at removed tableau at the number
of tableau in card
[Music]
um
that might be right actually that was
right you're a genius
so rule C us you're a genius look at
that beautiful oh man ooh and oh and
look it's drawing over the other card
that was that index well it was at the
seventh the seventh column that's
amazing I love it
but of course I try to get access to
tableau and it's nil but that's okay
because we can make we could do checks
for this we can check to see whether
it's null or not and if it is null we
can just say where do we say that where
should we say that probably
probably do something like if tableau is
equal to nil then just break out
probably yeah so rule good job that was
a great great catch on your part a very
subtle thing I don't know why I put one
in there oh this is just no loop to
break here return so now if I go over
here click this card again nothing
happens and at least doesn't break which
is good
however it's not letting me pick it up
again which is kind of unfortunate we
can say well actually notice should do
we can we can enforce this in up here I
can just say picked up is equal to true
and then I'll say if tableau is equal to
nil here then we'll return right so now
I should be able to just pick the card
back up again which is great all this is
fantastic
however these cards are both now in the
in the staging area so both now those
cards have their own separate hierarchy
their own z-index as David referred to
it and so that presents another side
problem however we don't care too much
about that because we're never actually
going to be using the game in this way
we'll only actually ever be able to put
cards onto other tableaus and in the
event that something like that happens
where we are on top of another card it's
going to and notice the Queen was added
to our staging area last so the Queen
action has priority over both the ACE
and this ace and over everything else in
the entire application this King same
thing now it has priority over
everything because we added it last
excuse me last to our staging area
however we don't care about it too much
if you release the card without putting
it down it should snap back to its
original position yeah that's gonna be
the original or the end behavior that we
want to strive for something that we'll
have to cover in the next stream because
this current stream we're running low on
time this has taken a tremendous amount
of time time flew by during this Jam I
apologize that it was a little bit slow
little bit of a crunchy stream today a
lot of functions a lot of logic we have
about 10 minutes left before and I have
to get out of here fairly urgently
because I think there's some some videos
they may be shot in here but we were
able to at least sort of get things
bootstrapped up built up in a way that
soon we'll be able to do parent-child
relationships and move things in the
right position and then easily logic
check that we have a winning condition
that that part is pretty straightforward
the hardest part of this whole game is
enforcing parent-child relationships and
additionally also doing like dragging of
multiple cards together and making sure
that we can put cards in different
stacks and not have them stage actually
enforce that they go back to their
original position if not their new
position if they fulfill the criteria
for getting into that position let's go
ahead and commit this as being and I'm
just gonna commit get add everything
[Music]
stacks in right position with staging
area staging area is important because
that's going to be where we do hold the
card when we do want to click it later
on so that was a big big addition to the
a big addition to the the code base we
didn't make as much progress as I would
have liked to make I would have liked to
make at least the amount of I would have
at least like to have us be able to
click and drag stacks of cards but in
order to do that we'd need to be able to
click and enforce that a card go on to
another card and we ideally want to
check for the numerical difference the
correct numerical difference we want to
be able to make sure that they are off
suited and once we do that then we
establish parent-child relationships
once the parent-child relationships are
established we can click a parent card
drag it around have it drag its children
around but that's gonna take much more
than 10 minutes unfortunately I'll
probably take another couple of hours
and so that we don't spend so much time
in the next stream not implementing
solitaire and we actually finish what I
think I'm gonna end up doing on the next
dream is actually make sure we come into
it with at least a solid idea of what to
do if not some
starting code maybe the hard parts at
least flashed out because the easy parts
you know ensuring the suits are correct
making sure it's there next number in
the parent-child relationship or sorry
I'm not the parent I'd like to make sure
it's the next number in the Tablo making
sure that the cards we put into the
stacks are of the right suit and the
right number sorry with ace working up
to King all of that stuff is actually
pretty easy the hard part again is just
this manipulation of layered rendering
and stacks and this in the the parenting
that's that's the hardest trickier
that's the harder trickier part of this
of this implementation so again
apologies if this was a little bit
lackluster if you're watching this I
will not feel too bad if you skip
through a lot of it and end up watching
part three because part three is where
we're actually partly gonna do most of
the juicy stuff because we're gonna run
a little tight on time I'm just going to
I think say this will be it for today's
stream and I'll stick around for maybe
five to ten minutes for questions so
yeah I mean we all together we did a lot
we did a lot of rendering we did a lot
of a lot of game development
unfortunately is implementation of a lot
of the less exciting stuff you know
things like all the hidden functions
getting ready to you know the thing of
the recursive functions where you can
start establishing that the the child in
things like pick up here
things like place down where we know
we're eventually going to need to place
our card down we're gonna need to check
whether it's a single card whether it's
a parent card we're going to I think we
didn't do much of this update here but
we did a lot of stuff here and update we
had to refactor that quite a bit we
ended up actually doing the Judah the
tableau generation today which was
sizable the rendering of the tableaus as
well the offsetting
layering all of all of our functions
else that they're pretty readable Andre
says not everyday in game dev can be
particles day that's true yeah
unfortunately oh yeah we started off
rendering all this stuff down here too I
ended up factoring up back up to the
render tableaus and render pick up cards
function we didn't really do much with
dec actually but we did have the the Dec
rendering here not which is nice I mean
it's just a placeholder but eventually
we're gonna click this deck and it's
going
create one of its cards it's gonna add
basically to another table a new face-up
card right and so that we'll be able to
actually click and drag around and
manipulate and that's gonna be kind of a
side tableau of sorts a side table but
we won't be able to put cards into it
they'll just be from the deck so there's
a lot of bits and pieces here but we're
making making progress step by step but
yeah if anybody has any questions
definitely let me know now is the time
to ask if anybody wants to share any
projects they're working on as well
w-will that's why we're using the
fisher-price shuffle he had a
fisher-price shuffle I like that's funny
parent-child relationships it'll be a
psychology kind of game yeah not quite
not quite no when I found that funny
fruit Allah Terry Froy Allah Terry says
it in me unfortunately that might be a
little bit of a twitch delay I'm glad we
were at least resolved thanks to Sir
rule CS for pointing out the the issue
we were having the fact that we can
click and drag this and now it's on its
own separate layer we've layered this
out that part alone was somewhat
challenging just because now we have to
like reshuffle memory and get it so that
things render in the right way and we
had a double render loop I actually
think the double render loop the double
click live was part of the problem but
the table removed at index one was
probably the larger part there but it
occurred to me as we were doing it that
on the same frame if you click any test
and you allocate to that side table that
then gets updated right after your main
table then they're both going to check
for them being clicked and then
immediately it's gonna place down so I
know right now I know I understood yeah
yeah it's funny funny remark
I don't think there's any necessarily
better terminology anchoring maybe I
guess you could say anchoring
relationship but parent child's has to
be common especially in like HTML like
the Dom and stuff like that child nodes
parent nodes child nodes it's I think
you Vic what it's just an easy thing to
think about parenting is perfect some P
some parents might disagree with that
statement andre some people might not
think that parenting is perfect i've
heard from many that parenting is in
fact stressful
it can be also in trees oh yeah yeah
true you have the the I guess the root
node to stick with the tree terminology
and then you have leaf nodes but also
they do refer to a lot of the time trees
as having parents and children since
there's a wall I'd like to point out
that yesterday was on Drew's birthday oh
happy birthday Andre that's awesome
didn't realize it was your birthday I
didn't see it on Facebook Facebook
didn't notify me to be fair I don't
check it too much on the weekends so it
might be part of the reason but happy
birthday I hope you spent it well hope
you spent it doing the things that you
enjoy doing
absolutely
and again any questions on the code base
on love 2d on games and cs50 bellick
here saying thank you for the stream my
pleasure thanks for sticking around
sorry it was a little bit drier today
than it normally is this was a little
bit of a like I said a more nitty-gritty
type stream and engineering stream
[Music]
programming is complicated sometimes and
bugs are hard sometimes to see those are
those are subtle you know you the one
versus the length that can cause a lot
of headaches and game development is is
worse because in games a lot of the time
it's not obvious where something is
happening it's just obvious that there's
a visual disturbance you don't
necessarily know unless their tuition
where it's actually happening and to
whomever's point earlier who mentioned
debugging bach anova I think it was
something like that it can be
challenging but we are going to finish
this game whether it's in this stream
not sorry whether it's in the next
stream or some other stream likely what
I want to do is I'll spend a few minutes
just off-camera kind of figuring out for
this one in particular because it's a
little bit a little bit meteor and I
want to make sure we have a consistent
flow for the next part I'm going to
probably pre do a little bit or at least
tinker with it and at least know in my
head do I need to do and then we'll have
kind of a trajectory I might take some
notes that everything's still from
scratch but it's just smoother less less
figuring out of bugs because I don't
want to waste anybody's time so rules
those things called deeply nostalgic
yeah well my question I'm glad that you
enjoyed your a brave soul for life
programming I enjoy it I don't enjoy
lols like terrible lols
trucha nice did we have solitaire part -
not on the twitch schedule part - should
have been listed out is that not right
and actually part three if there's part
three listed that needs to be removed
we actually need to reallocate time this
week yeah part yeah part three the fact
that it's still there that needs to be
shifted so we're actually doing no
Psalter part three this week it'll
probably be next week we are doing
cookie clicker on Wednesday that is
still happening that one's quite a bit
easier and simple and will be fun on
board tricking people new to game
development and also thank you for
brushing tutorial Spiller and ng AFS and
Saurabh ooo three four five thank you
very much for the follows no stream
tomorrow tomorrow we're just doing yeah
we're not doing any stream tomorrow
despite what the schedule says it's my
batting to update that that needs to go
away
solids are part three will likely be
either next week or the week after that
like I said unfortunately we have to
shift things around a little bit cookie
clicker will be on Wednesday and
JavaScript will be on Friday so stick
around for those both of those at 1:00
p.m. the cookie clicker one a very nice
on-ramp like I said for brand new folks
to the game development and JavaScript
if you're looking for more of a web
development sort of on-ramp and both of
those will be a lot smoother because
those are a lot simpler than been
solitaire and next electrician will be a
lot nicer and smoother too we love the
problem-solving awesome oh and a steel
Eric no problem today's stream was a
little on the dry side it was a lot of
sort of sort of like foundational
programming for higher level stuff that
we'll get to in the next stream sort of
building our way up piece by piece but
we do have a nice game board if you want
to see what it looks like here's what it
looks like now we have all the cards
that have laid out this is more or less
what the game is going to look like from
the very beginning except this will have
cards that we can draw we can click and
move around these cards which is pretty
cool notice that they take rendering
priority despite where they are on the
game map unfortunately we don't have
anything much beyond that the next
stream is going to involve establishing
parent-child relationships it's going to
involve us being able to flip hidden
cards which I just did right there and
it didn't work too well because
unfortunately that part is still bugged
but that was another thing we
implemented today the ability to flip
with right-click hidden cards and our
stacks
but right now it seems to be bugs such
that it reveals all hidden cards even
though we supposedly fixed that earlier
but you know things happen
bugs happen I can't right-click this
card and have it work so we did account
for that issue however I move this off
and then right-click we do reveal all
the underlying cards so we're halfway
there but we still have a ways to go and
we also buy next stream we will not have
any more of these cards being staged we
will not have any staging area we will
only be able to place cards into new
areas or have them revert back to where
they were before we click to them so a
lot of things going on and lastly of
course we'll be able to take cards like
the ace and put them up here and start
building up our piles and we should have
some sort of marker to signify that
these cards are indeed being stacked
maybe by tenting them yellow or
something so they're visibly locked here
and we can't move them around like this
make them build up pursuit and based on
their value oh and another thing we also
need to consider is the ability to not
only move things off of the grid
appropriately but also make sure that we
take a king for example and are able to
reallocate it to a new tableau so that's
an important thing so shifting more of
this card shifting which is an important
aspect of this game but we're making our
way there we have a lot of work to go
but we're doing stuff ok
trucha nice oh I missed the stream of
the schedule mentions this would be on
Tuesday so no this is Monday we're doing
solitaire part 2 Tuesday was gonna be
part 3 but we actually need to shift
that that's actually gonna be next week
so I'm gonna immediately edit this this
is going to be as a ten minutes after
the stream it's gonna say no stream and
then then we'll probably end up doing a
solitaire part three next week or the
week after depending on how time allows
we have to unfortunately shift the
schedule a little bit but we will be
doing cookie clicker on Wednesday and we
will be doing JavaScript basics on
Friday those two are still on the
schedule and will be on the schedule for
sure
part three has always been kind of
tentative and that's why we didn't
publicize it part two
is has been publicized and that is
reflected as strong a Monday on list on
the twitch stream debugging lows are
great for us to learn don't worry about
it says Ashley I feel terrible about
them though
trucha nice it's still off a day even if
it counts for the 1 p.m. to 7 p.m.
conversion that's weird because for me
I'm seeing it reflected correctly so I'm
not entirely sure how you're seeing it
off because on mine it says Monday other
people can can you confirm and tell me
if it shows it as being correct
the schedules appear in your local time
they do for me says it ain't in it I
think everything is saying it's weird
interesting I see it as correct I hope
it's not a bug
[Music]
interesting what time zone are you in
trucha nice if you can tell me what time
zone you're in actually I'm not that's a
very strange CET happy Sunday on Monday
I definitely don't have that online
that's weird
I will look at that and debug that
because as far as I was aware him this
has been accurate and it looks good but
I apologize for anybody who has been
looking at this and seeing things
shifted today I'm not sure why this is a
news a new scheduler widget it might be
broken for some time zones so let me
investigate a little bit more maybe by
changing my clock or something to a
different to a different thing yeah East
Coast that's correct that chat cat is
saying the schedule looks good
oh it supposed to be plus 5 interesting
I think when I I did it at plus 5 it was
bugged I think I might have tried that
initially I don't remember I remember
having to futz with it to get it to show
the right time I'll take a look at it I
apologize for the folks who it's broken
for to set the record straight tomorrow
Tuesday no stream Wednesday
1:00 p.m. Eastern Standard Time we'll be
doing cookie clicker and Friday 1:00
p.m. Eastern Standard Time we'll be
doing JavaScript basics including syntax
a little bit of Dom stuff like document
dot get element by ID and query selector
and then lastly we'll be doing a little
bit of dynamic bootstrap in JavaScript
to sort of tie together the last javis
or the last bootstrap stream that we did
where we only looked at the CSS parts so
kind of tie in the new with the old and
everything will be great cool all right
we're at 404 I've gone over a little bit
I know that some folks need to get in
here to use it the video software so
apologize to them thank you all for your
patience today like I said not the most
exciting glorious stream we've had it
was a little bit more down you know get
your hands dirty type of stream and
we're into the weeds as we say but next
stream will sort of have a smoother flow
so this was cs50 on twitch this was
Salter part two stay tuned for part
three next week and see you all on
Wednesday for cookie clicker which is a
great if you're brand new to game
development so have a good rest of your
evening