Lesson 1 of 11
Understanding the Problem
In this lesson
The pair agree how to pair program (external link, opens in new tab), set up Visual Studio with NUnit (external link, opens in new tab), ReSharper and TestDriven.NET, and write a first test that a new board position is empty. They cover units of work (external link, opens in new tab) with three kinds of end results (external link, opens in new tab), a ReSharper test template, factory methods (external link, opens in new tab) instead of setup methods (external link, opens in new tab), and removing assumptions one at a time. Then they drive out removing a black stone surrounded by white stones, in a visually laid-out test, and debug an index out of range bug at the board's edge.
Transcript
[00:14] (external link, opens in new tab) >> Okay. So are you familiar with how pair programming (external link, opens in new tab) works? >> No, no, I'm not familiar. So the basic idea is that we are both trying to deliver the same product and so we take turns or we switch every few minutes. When one person is the driver, the other person is basically helping out. So you might you can start on the keyboard and try to create your vision of what the go game looks like. We can basically do it together and we can switch whenever we want to.
[00:48] (external link, opens in new tab) Okay, >> that makes sense. >> Okay, makes sense. >> so just so you know, the way I like to do things when I'm doing TDD (external link, opens in new tab) is that also I want to make sure that for example I get the I like to start with the code very very clean. So I remove all the using as well. So I just remove all the unused directives and also the class name should have a a good name here. >> what what should we rename it to? So, I was thinking the first test would probably be interacting with the board directly.
[01:21] (external link, opens in new tab) So, like putting the stones on the board. So, I maybe like add stone tests. >> Add stone tests. >> I are you talking about just with general maybe board tests and then the scenarios would be adding stones. >> Well, let's start with what do we want to demo out of this session. Okay. >> What do you want to do? >> what was the issue that I was having problem with? I forgot.
[02:11] (external link, opens in new tab) Well, the thing I want to demo out of this is interaction between multiple objects, right? So, >> yeah, but in terms of a deliverable product, what were you trying to accomplish? Oh, I was trying to accomplish a game that two players can interact with each other or well basically like I guess what you call like an engine where I could add in like AI to replace the charact replace a player but I wanted like a a full game for the go game. Is that is that what you were asking? >> Okay. So we can start with maybe full game tests see what happens.
[02:46] (external link, opens in new tab) >> Full game test. Okay. >> So just F2 to on the class name. Okay. like full full game tests and that will also rename the file name in the solution it's for which is amazing cuz Visual Studio still doesn't do that after like four or five years I don't know why >> okay next we have to make this a test class so we have to add NUnit (external link, opens in new tab) to the package through add NuGet
[03:17] (external link, opens in new tab) >> okay >> so do you remember how to do that just install package Now, at first, we're just going to write the tests and the production code in the tests >> and then we can refactor them out later. >> Okay? Right? >> Because the goal of this is to actually produce real code that works. >> It's not just to have tests. The goal is to >> I call it test driven development because the idea of the test is to drive development, >> right?
[03:47] (external link, opens in new tab) Right. >> So, we're going to start with the happy path stuff to get things going so we can demo something so we can get feedback. >> Okay. >> Okay. So, we have NUnit and now we can add the test fixture attribute and the tests. >> I forgot does the test fixture go on top of the class? >> Yes. >> Oh, do I what's the shortcut? Was it alt enter? >> Control alt space if you want to get a nice completion here. Control alt space.
[04:18] (external link, opens in new tab) >> I I did that. >> Interesting. >> Huh. >> The things next to it says alt enter. >> Yeah. But if you want to if you want to have a nice completion of let's see let's see what the ReSharper configuration here is. Hold on. Visual Studio. We're using the ReSharper 2x which is what I'm used to. And in there >> maybe I I misunderstood. I supposed to do test. Oh, sorry. >> Okay, you write it.
[04:49] (external link, opens in new tab) Test. Just use the word test. >> Control alt space. >> I just start testing it and then control alt troll >> alt space. >> Control alt space. All right. How would you give it a try and let's see if you have a better >> Okay. Test fixture. Control alt space. No. Oh, yeah. For me, it's a Mac, but you know what? Let's just get rid of this and say fixture and be done with it. >> see, >> there you go. >> Oh, there you go.
[05:19] (external link, opens in new tab) Now we have an alt enter here. Apply to all ReSharper shortcuts. From this moment on, it won't bother us anymore. >> Okay. >> and we can write our first test. >> Mhm. >> Okay. So, where do you want to start? What should be a good move to start with? >> So I from the books I read like the the first test is basically a very easy test, right? So >> it should be something that you can it should be I call it a unit of work (external link, opens in new tab). A unit of work is something that you usually start with a public method and it ends up with one of three end results (external link, opens in new tab).
[05:57] (external link, opens in new tab) So you could have a value returned. >> You could have a state change to a system. So the system behaves differently. For example, it used to say X, but then I did an action, now it says Y. >> Or you call out to a third party like logging infrastructure, >> right? >> So, >> okay. >> What do you want to do? >> I think the first one should be adding the stone to a board. >> Okay. And then what is the change state? The change state is that that position you add it to goes from like there's no no stone to having a stone.
[06:36] (external link, opens in new tab) >> Awesome. Okay, let's do that. So, so write the test. What's a good test name (external link, opens in new tab)? >> So, you the way according to what you like it, you like it with scenario and the result and with the method, right? Okay. So, it's not just a method for us. It's the unit of work. Remember, a unit of work can be something even bigger than a method. Could be a whole classes. As long as it's all in memory, you should be okay. >> Okay. So, add stone. >> Yeah.
[07:06] (external link, opens in new tab) >> scenario. Well, add stone kind add the unit of work and scenario right now kind of sounds similar, doesn't it? >> Sure. Let's do that. >> Add stone. >> Well, add stone. Stone is added. You mean that it succeeded? Under what scenario happened? >> at >> right. Is that the scenario? >> Yeah, that might be good. That position is empty. Maybe I know that. >> Well, you can say to empty position instead of add stone to empty position cuz you're just repeating yourself there.
[07:42] (external link, opens in new tab) >> Say it again. >> Well, you you don't have to say add stone twice. You can just say add stone to empty position. >> I see. empty position and then >> success or >> well no what what is the expected behavior now >> is it position is failed or >> position >> yeah position filled >> okay >> so now before we actually write this test >> Mhm. Now that if a position is filled, it also has a default value.
[08:16] (external link, opens in new tab) Right. >> Right. >> So we can start with an even simpler test by having just checking the the state of a default position without doing anything. >> Okay, that sounds very interesting. >> So go just above that and see what we can do. >> so I guess the unit of work would be like query position or get position. Now, the question is, are is that what you're trying to do? Will you have a get position in the game? The get position status.
[08:47] (external link, opens in new tab) >> Yeah, get position status. >> or is get position status something that's internal that's going to be used by something else? Does the user have to know the the status of a position? >> Yes. >> Okay. >> Get position status. >> Or just get position status, sir. Okay. >> >> now that's interesting. >> Well, empty position is the expected value, right?
[09:18] (external link, opens in new tab) >> Right. >> initial >> you can say that yeah, initial position might be good. >> Initial status >> is empty position. Okay, that's good. I think that's a better starting test. >> Okay. >> Okay. So, let's put the other test. >> Do another one. Just comment it out for now. Just leave it there. You can comment it out. >> Oh, shoot. >> Don't worry. You don't just delete it. Who cares?
[09:48] (external link, opens in new tab) That's why God created source control. >> yeah. Sorry. I'll just comment it out. >> Okay. Now, don't forget the test attribute here. >> Okay. Perfect. Now, if you're not sure how to run with this, you can start with the end. You can actually say, well, I know what I'm expecting. So, let's start from that.
[10:19] (external link, opens in new tab) >> Something empty. >> Are you getting back an enum or just a true false? >> I was I was going to Well, I feel kind of tainted from what I written before I did the enum. >> Okay. So, >> can it have more than the true or false? >> Yeah, either white, black, or empty? >> White, black, or empty and go. >> Interesting. >> Yeah. So, the there's two players, white and black. >> And then if there's no stone, empty. >> Uh-huh.
[10:50] (external link, opens in new tab) Okay. >> So, I I could either split in two methods like does it have a stone or not. >> Mhm. >> That's one method. The other stone is like what color the stone is. or I combine it in one and it's you number three, right? >> Whatever you want. Whatever is more readable to you. >> Okay. Okay. So would I do like a board like get position? >> No, no, hold on. You just just assume that you get back a result.
[11:22] (external link, opens in new tab) Then we'll figure out where you get the result from. >> Okay. So I I do a result. >> Exactly. Now hold on. Something about the way you write stone empty. I'm saying what I'm thinking is that >> maybe stone is not a good enough enum name. It could be stone status empty. >> Okay. >> Why why would stone not be good enough? >> because a stone means that you're looking at a stone, not at a position.
[11:54] (external link, opens in new tab) >> Okay. So it might be even position status instead of stone. >> All right. Position status sounds more clear. >> Okay. >> Keep on switching it. All right. Okay. And so no where are we getting the result from? >> So we get the result by quiring the board. >> Okay. So that so if you had the ultimate design assume that everything is already perfectly designed >> right >> how would the API look like?
[12:26] (external link, opens in new tab) How would you get the quer? How would you get the result? Just just get the result from there. >> Right? So do you have to have an X and Y? What's the simplest position? What's the beginning position? Simplest position might be one one. >> Okay, >> because I was thinking the board goes from one to 19.
[12:57] (external link, opens in new tab) Instead of doing a zero zero, I forgot what the term starting from zero. Start from one instead. >> Well, that's you're the go master here. It's your domain. So, >> All right. >> Okay. So, I wouldn't actually declare the position status as a result just before. I would just say position status result like this. So, oh, I tried to never mind. Different different shortcuts here cuz I'm running on a Mac, >> right?
[13:29] (external link, opens in new tab) >> Just like that. Control shift L. >> sorry. >> Okay. >> Okay. So, position status result board get position and Okay. And how are you getting the board? You just create a new one. >> Yeah. >> Okay. >> Yes. do that. >> All right. >> No, it's not an eye board. >> Oh, my my bad.
[14:01] (external link, opens in new tab) >> And it's also in the beginning. It's not an eye, just a board. >> Okay. So, we don't want to do All right. You're Okay. So, you we don't go with interfaces in the beginning. You start with the simple solution that works. Okay. You don't have to abstract away nothing because you don't have anything to abstract. You don't have any problem. >> Okay. >> Okay. Let the design emerge as things go. Okay, that looks pretty cool. I also like to separate these so that it's more readable.
[14:32] (external link, opens in new tab) >> Right. The arrange acted a certain thing. Right. >> Exactly. And also, you'll notice that you call this get position status, but you felt more inclined to just say get position. >> Right. Right. >> So, which one do you like better? >> Like the >> Okay. >> All right. >> So, now we can make this compile and see it fail for the first time. >> Okay. So, >> so just just make everything compile by going to each to each of the red ones.
[15:05] (external link, opens in new tab) Okay. and pressing alt enter and generating the class right here. Don't worry about it. Okay. We can always move it later. >> I see. >> Okay. >> What did Alt enter do? Did alt enter run it? Where? >> Alt enter. If you'll notice there whenever I'm on a red thing here, ReSharper has a nice lamp here. So, it tells me possible actions for a pro possible problem. >> So, it's like the genie >> just it always tries to help. So you can go to position status and generate that as well.
[15:38] (external link, opens in new tab) >> So it's a class. No, it's actually not a class. Interesting. So you can create it as a class and then then turn it into an in I guess. >> Okay. Interesting. Oh wow. Okay. Wow. Very cool. >> Okay. Now we can go on into the get the position status.
[16:09] (external link, opens in new tab) Hold on. Hold on. >> You're still in here. So, position status is what you want. Tab. Int what? >> Oh, >> int X. Int Y, I guess, right? >> X, right? >> And then tab. Int Y. Tab. >> Well, how come it adds a I next to it? I don't know why you have an I next to it. I have no idea. Okay. And and what I don't like is to have a notimplemented ex exception
[16:39] (external link, opens in new tab) Because I like to have my test fail not because of something too obvious, but I like the test to fail for something that feels like a bug, >> right? >> So instead, I actually will return the wrong position status. >> So let's call it black. Okay. Okay. So now we can just still make it compile and then we should see it fail. So make it compile. Create an inner member empty.
[17:15] (external link, opens in new tab) >> Well, how come it's not how come it's still red? >> H >> why is it still red? >> I don't know. Interesting. I don't know. Maybe just call it empty position. I don't know. See what happens. Maybe it's a special word or something. Control controller. >> Okay, we just call it empty stone. Maybe it's a just a save word. Saved word. Like special word.
[17:58] (external link, opens in new tab) >> Okay. And just remove the empty one. Okay, interesting. >> Or maybe empty position is better. I don't know. What do you think? >> Right. You're definitely right. I was just trying to Okay. Okay. So now we can run this test and fail. So the first time you run the test, you just rightclick. Let's right click on the whole project. and run tests with TestDriven.NET.
[18:30] (external link, opens in new tab) >> Okay, so if I run this, I should be able to see. >> Okay, expected empty but was BlackstoneOne. And you can also see the line number. >> Mhm. >> One fail. That's what we care about. Whenever you see this, you can also double click. So you can double click here and you have this nice marker over where you got to. Okay. So now we can go ahead and make this test pass in the simplest way possible (external link, opens in new tab). >> Right?
[19:01] (external link, opens in new tab) >> Okay. >> We just change this. Right. >> That is perfect. Okay. Now we can use alt R to rerun all the tests. >> Does alt R automatically build it? >> yeah, it also rebuilds it and it repeats the last action. >> Okay, >> perfect. Okay. So now we have the first loop in TDD. >> Okay. Now let's go to the next test that we wanted to write.
[19:37] (external link, opens in new tab) Okay. So add stone to empty position. Position filled. >> Mhm. >> Okay. So now we're going to do a statebased change because at the beginning we get a wee know that initial status is empty. >> Mhm. But then the initial the the position is going to say that it's either black or white. Right. >> Right. >> Okay. So just don't forget to add the test. >> But you know what? Actually before that let's configure the environment a bit better. >> I want to teach you another trick. >> So I like to use the ReSharper snippets to generate tests.
[20:11] (external link, opens in new tab) So what I'm going to do is I'm going to copy the whole test here. >> Okay. >> Crl C. And I'm going to go to the ReSharper Template Explorer. And now, do you see the icon for creating a new one? Like a plus. >> Is it this one right here? >> Yeah, new template. >> All right. >> Create. Click it. Okay. So, now we can we can close this window here. Word. Shift escape.
[20:41] (external link, opens in new tab) I think that doesn't work. Can you drag the window? Cuz I can't. Drag the window to the side or something. >> This this >> the template is for window. Just drag it away so I can Yeah. Okay, perfect. >> Do you want to put this back? >> Okay, just close it. >> Yeah. Now I want to write the word test here. And every time I write the word test, I want this code this code to appear.
[21:12] (external link, opens in new tab) Okay, for now I'm just going to press Ctrl S. Go back to the code. And now if you wanted to, we can just say test tab. We get this. >> Wow. >> Yeah, it's not it's not good enough yet. We want to make it a bit more generic for our taste. So >> I'm going to remove the whole thing here and going to replace it with dollar and dollar. That's a special keyword that says this is where the cursor is going to end up when you finished all the tabbing.
[21:44] (external link, opens in new tab) But also dollar anything you put between two dollar signs >> becomes generic. So you can say this is the unit of work. Crl S to save it. And now if I go to test and I press tab, I get this. >> Very cool. >> Okay. Pretty cool. >> So, let's just go ahead and make the two dollar signs here and say scenario
[22:18] (external link, opens in new tab) And tab expected behavior. And we should be done with creating a new test for now. So, control Z. Okay. Now if you press test we can have a nice one. So add stone to empty position
[22:49] (external link, opens in new tab) Position is filled app. Okay. >> Okay. >> So it should be easier to write new test from now. I'm just going to delete this one. >> Very cool. >> Okay. Okay. All right. So, we'll start with the assert K.
[23:37] (external link, opens in new tab) Oh, that's good. >> Press escape. Wait a minute. Which stone? How do you know it's black? >> You're right.
[24:23] (external link, opens in new tab) Now, this is where it starts to make a less sense, >> right? Because can you add a stone to an empty position status? Can I add a stone? Oh, like empty position status. Well, it it doesn't sound nice in code, I guess. >> Mhm. >> It would basically be like removing the stone. We resetting position. >> Yeah. >> Right. Okay. >> Interesting. >> So, >> it might tell us that maybe the design is kind of problematic.
[24:54] (external link, opens in new tab) >> Okay. >> Maybe we need a different different enum for that. Okay. >> So now you can say well before changing something just say what you wish the API looked like. >> Right. So instead of position status, you can just say stone type or something. Yeah, stone color. Awesome. >> Mhm. >> another type to think about is just adding the stone itself, which already has a coloring status,
[25:26] (external link, opens in new tab) Whatever you want. >> Oh, you mean like a stone object? >> Yeah. >> What do you think? >> I I think no, because the stone is not going to have much of anything else. It's just going to have a color. Okay. Okay. >> To just be >> sure. >> I mean, is that how people normally do it? >> there is no how people normally do it. That's the point >> is that you start out with something and it needs to be
[25:56] (external link, opens in new tab) Maintainable later, >> right? >> Okay. So, add stone to position with stone color black. And pos and I think that what you get back from get position status should be not not empty instead of black zone. >> Okay. >> Right. >> Does that make sense? >> Okay. Yeah, that makes sense. Now the nice thing about this is that since the most of the design doesn't exist yet, we can easily change it and it's going to be cost us much less.
[26:45] (external link, opens in new tab) What do you think? >> Field does sound nicer. Right. >> Okay. So now we get to make this compile and see it fail. create the class and then turn it into an in. Yeah.
[27:29] (external link, opens in new tab) Oh, I forgot to tap the >> Mhm. So, just click on Yep. Stone color. Hit X tab. It's adding a I >> don't know why. I have no idea why. >> How do I How do I skip that? >> Just tap by press. >> I think it's just enter. All right, cool. >> Okay, just make it not do anything, right?
[28:02] (external link, opens in new tab) >> Just remove the whole line. It still won't compile because you can see all the red stuff over here, right? If you can see red means it's not compiling. You don't even have to try to compile it yet. If you can see red in this square, it's not going to be able to compile. I see. >> Okay. >> Okay. So, let's add this one. Just failed. And >> why still says red?
[28:33] (external link, opens in new tab) >> Yeah, it's weird. Maybe it likes a comma next to it. No, >> let's see. No, that shouldn't be a problem. Position status filled. Not sure why call it filled position. Let's see. Let's wait. Let's see what ReSharper tells us. Alt enter. Add argument name expected.
[29:11] (external link, opens in new tab) No, that we don't care about that. I mean we can say basically what it tells us we can do that. See that doesn't make a we don't care about that for now. But we can say filled position maybe equal space fill position. I don't know why I have no idea. All right.
[29:42] (external link, opens in new tab) >> okay. So, now we should be able to rerun all the tests and one of them should fail. >> Right. >> Right. Right. >> Okay. One passed, one failed. So let's make all the tests pass in the simplest way possible. >> So, what's the simplest way possible?
[30:21] (external link, opens in new tab) >> adding a variable. >> Nope, that's not the simplest way. >> Is that a way? >> I mean, yeah, I guess so. Maybe it is. >> what what was your was what you were thinking? Well, at the beginning I was just thinking of of of putting Yeah, but you have to save the value so that get position somehow saves it. So you can just make return position status return whatever is in the variable at the top. >> Right. >> Okay.
[31:04] (external link, opens in new tab) I think you have some extra plugins trying to to add stuff. Something probably with C++. >> No, it's I keep on pressing cap caps lock cuz I have caps. >> So just yeah, you can reenable the caps lock thing if you want. >> Oh no, it's fine. >> So position status will be filled. Awesome. >> And initial >> alt R. >> Yeah, of course. No, no, no, no, no. That's That's already too complicated.
[31:35] (external link, opens in new tab) >> That's too complicated. >> Yeah, you can make all the test pass without that, right? >> You agree? >> M I don't think so. >> Okay. >> But we'll try. >> Oh, yeah. I agree. I agree that that's missing. Sure. So, you have to add that the default. I agree. >> Yeah, because I set it. >> Mhm. True. >> All right. >> Okay. Two passed. Now, obviously, this is an amazing and beautiful solution. It's not good enough.
[32:05] (external link, opens in new tab) But we can also refactor because we no longer need the black stone here, right? >> Right. >> We can just remove that. >> Let's see. Did we break anything? >> Nope. >> Cool. And is there anything else? We probably need the white, but we'll take care of that when we need it. So obviously this is not good enough. Right. >> Right. >> And what's not good enough is that
[32:36] (external link, opens in new tab) I mean can you can you put in words what what you want to fix here? >> Well given position X Y. >> Sure. >> We're only checking one position. >> So we're always assuming the same position, >> right? >> Okay. And that's the big problem. And now the way I I see TDD these days is that you start with the simplest things possible which means that you make as many assumptions as possible and then you remove each assumption one by one just like peeling an onion and each one is makes the code more and more generic.
[33:13] (external link, opens in new tab) >> Right? >> Okay. So now we can remove the assumption that we always know the position. So we can write a test with a different position. Before we do that, we have to make the test a bit more maintainable cuz right now we have a maintainability issue. Can you see it? >> we're declaring a board every time. So, we have a setup fixture to initialize the board. >> Oh, why why is it a maintainability problem?
[33:44] (external link, opens in new tab) >> It's a duplication. It's duplicated in both methods. Redundancy is that the word used? >> Well, yeah, it's redundancy, but the it's definitely that, but the problem is that later we can have we can add a constructor to board >> and then we'll have to fix all the tests with that. >> Okay. Right. >> Okay. Now, I don't use setup methods (external link, opens in new tab) anymore. I'm actually writing that on the second the second edition of my book is that I'm trying not to use setup anymore. >> Okay. >> Because if I use setup method, then people will have to read the test in both places,
[34:18] (external link, opens in new tab) >> right? to understand what's going on. >> I remember reading about that in someone else's blog. >> So, I refactor into a factory method (external link, opens in new tab) instead. >> Crl Alt M. Let's see if that will work. Create a method. Make board. Okay. >> Okay. And the same here.
[34:52] (external link, opens in new tab) Alt R. Let's see if we didn't break anything. Okay, so that's the basic stuff. It can be static for now. We don't have to do anything about that. Cuz it's part of the tests. But now I don't need a setup method and I can see exactly where board is created. Oh, I see. >> Okay. >> Okay. Very cool. >> Okay. So, let's remove an assumption about obviously the position is always assumed to be the same.
[35:22] (external link, opens in new tab) >> Right. >> So, what we're going to have to do is we're going to write the same test with a different position, >> but we're going to expect >> an empty position. >> Do you agree? >> Right. Is is it going to be the same test? Really? >> well, there could be we could reuse one of the tests to do the No, I think to to get it to fail, we probably need to add a different test where we add a stone to a position, but check a different position to make sure it's
[36:02] (external link, opens in new tab) Still returns empty position. I'm not sure. Maybe is that is that answering the question? >> Yeah. Yeah. I'm trying to see if we can reuse this test or not. And would it be readable if we did that? Okay. You know what? Let's create another test for now and see what how that looks. Right. Because if we reuse the test right now, it's still going to pass. >> No, I agree. I agree. But we can add another assert or we can replace the assert and have a parameter to the test where we can say add to this position check that position.
[36:40] (external link, opens in new tab) But we still want to check the original position. So I guess we need a new test. >> I agree. >> Okay. So create another one or unless you want me to do it. >> I want to watch you do it. >> Okay. Ctrl W. Let's see if that will work. D. But you know what? I don't like duplication. But I'm going to write another one with the with this. So add stone to
[37:22] (external link, opens in new tab) What would you say? Add to empty position. Empty position. other empty position is unaffected. I guess that's one way to think about it. >> Okay. >> I agree. But I think this should probably be a lowercase a let's see.
[37:53] (external link, opens in new tab) So we would have a make board. Crl altv to extract a variable from that. Ah control shift space doesn't work here. Huh? Position
[38:27] (external link, opens in new tab) Is it? Oh, stone color. color black one and one. It's almost the same test. >> or get position status of one and two. >> Mhm. and Ctrl AltV again to get the status
[39:02] (external link, opens in new tab) What do we have? We have a position status dot empty from status. Okay. Alt R. Two passed, one failed. Okay. So why don't you try and fix it now? Okay. All right. So, is it
[39:33] (external link, opens in new tab) >> now remember you have to fix it in the simplest way possible. So, you can make as many assumptions as you want. >> Okay. The thing that comes into mind for me is just putting it in a two-dimensional array. >> Okay. >> Sure. or a list of tuples. Actually, maybe a list of tuples is actually even simpler. So,
[40:08] (external link, opens in new tab) >> as long as it's simple and readable, >> we know that there are 19 rows in each ver vertex. >> Okay. >> Are do we >> is it 19 by 19? >> Yeah, it's 19 by 19. I wasn't sure if that was not stable enough. So if I make constructor I mean
[40:59] (external link, opens in new tab) Shoot. guy >> and then what will everything pass now? >> No. >> Obviously because we haven't used that, >> right? I can make this incorrect for now, but I already know that minus one.
[41:34] (external link, opens in new tab) >> Why is minus one? >> Because we're I'm not doing a zero index. Is that the >> I'm doing a one index 1 through 19 instead of 0 through 18. >> Then wouldn't it be position status of 20 by 20? But then you would have 0 to n 0 to 19 which would make it I mean the length of the board is >> okay >> 19. >> Who cares? Let's make it let's make it pass. >> Let's not worry about it now. Can always change it later.
[42:06] (external link, opens in new tab) >> Right. Why are you setting the position status here in get position status? >> You're right. I I was not thinking clearly. I think you should turn on the the caps lock for you as well cuz you keep hitting it for for control >> breaking up for me. I can't >> Yeah, I'm saying that you should enable your caps lock to be control again if you want because I think it's hurting you.
[42:43] (external link, opens in new tab) All right, >> there we go. >> Okay. Okay. Now everything is passing.
[43:14] (external link, opens in new tab) How can we make things a bit more readable and maintainable? So I would say that 19 we can make that into a const for example. >> Right. >> Mhm. >> So we could that do that. Sorry. >> Oh, >> you going to have you go ahead and do that be faster. Do you how did how did you do that when you extract it out? Was it controlm?
[43:45] (external link, opens in new tab) >> Well, if you're not sure, you can always use your control shift R to get a menu of what you want to do. If you want, you can just select the 19. Hold on. Escape. Okay. I'm pressing escape here. Of course, it doesn't work. Yeah, I I switched three keys around. >> Control, shift, R. Nope. Which key did you switch? >> So I switch caps lock with control because it's the biggest key.
[44:17] (external link, opens in new tab) Yeah. >> And then I have my control key as the escape and I have my escape key as the caps lock. >> Oh dear. That's why some of my shortcuts don't work. Okay. So anyway, >> maybe >> control shift R in this >> control shift R. >> You see in extract method introduce field or move to resource introduce field for now. Replace two occurrences
[44:49] (external link, opens in new tab) Obviously. >> what will be the name of the field? >> Board size. >> Okay. And you can make it yeah private I guess. >> Sure. >> Okay. >> Why is it making a static? >> that's the default but I can just say private const int and then make it uppercase.
[45:20] (external link, opens in new tab) >> This one uppercase. >> I'm pretty sure there's an uppercase shortcut but I'm not sure. Just a just F2 to rename it or board size uppercase. Let's see. XUS one. It's always minus. I don't like this minus one thing. I have to tell you. >> It's kind of weird to me. >> It's unreadable.
[45:51] (external link, opens in new tab) Mhm. >> How do we get rid of the minus one? Just make sure we didn't break anything. >> Yeah. >> Forget about the implementation of the board for now of the array. How do we get it minus one? >> I'm trying trying to think what's the easiest way to make it pretty. If I don't have to use minus one, I can make the board size bigger, can't I?
[46:25] (external link, opens in new tab) >> Yeah. But then I guess when you treat like the argument zero, >> but I don't have a test for that, so I don't care. Remember? >> Okay. >> If I wanted to care about it, I would write a test for it. >> So, we could do that the next after we fix the make things more readable. >> Okay. >> Okay. Remember, I want things to be readable. So, I can always check for I mean, it's not like people can't send an x of minus one if they really wanted to.
[46:56] (external link, opens in new tab) Right. >> Right. >> And I'd still have to take care of that. >> So, what if I wanted to do this? I mean, for me, it just might makes it more readable. Other people might not like it. But that's the nice thing. You can make decisions about your personal taste. Alt R. Let's see what happens. >> Mhm.
[47:28] (external link, opens in new tab) >> Actually, we can make it still 19. Do we have to change it? >> Because we don't have a test for the boundaries yet. >> True. So now we can write tests for what happens what kind of message do you get when you're outside the board boundaries? Okay. >> Mhm. >> But I think that's pretty read readable. >> so we can write a new test that says, well, if I'm adding a stone to something that to a place that doesn't exist, we should be getting back
[48:01] (external link, opens in new tab) This specific message, >> right? >> But you know what? For now, I usually try to worry about these things later. So what because I try to go through the happy path first so I can say >> what happens when you're out of board position. >> Okay, >> I see. >> And then I can worry about it later. >> Okay.
[48:32] (external link, opens in new tab) Okay. So let's move on to more exciting things. You where are we going with this? Let's let's get closer to where you were what you were trying to ask me. >> Okay. I I don't think I understand your question. >> you sent me an email. How do I fake (external link, opens in new tab) this behavior, etc. >> Right. >> Okay. So, >> what do you want to Let's try to recreate your scenario. Are we close there to that or do we need to anything else >> to get to your scenario?
[49:06] (external link, opens in new tab) >> So, Well, we we still need to work on it a little bit, of course. >> Okay, let's add a couple more features. >> What do you want to do next? Which feature do you want to demo next? So we I want to
[49:37] (external link, opens in new tab) Add enough stones in the board and then after you eliminate a liberty for one stone, it disappears. So it would be like adding Well, I'm not sure if that's the next simplest one, but that's where I'm trying to head head towards, right? >> It sounds pretty simple. So exactly what you want to happen. >> So I want to set up the board so that there's a black stone surrounded by white stones. >> Sure. >> And and then when you add the last white stone, the black stone should be removed.
[50:08] (external link, opens in new tab) It should be removed on the next pulse or exactly after that? >> Exactly when the white stone is added. >> But should there be an event when it's removed? >> what does it mean that who removes the stone? >> The board. I was thinking the I was thinking the game the game removes the removes the removes the stone and the board just acts dumb to it. >> Sure.
[50:39] (external link, opens in new tab) Okay. So, why don't you write a test for that? a simple test that that uses the code the way you wish that the user would use it, right? Assume that the API is already there. You're just using it, >> right? >> To write a new test with the with a template. Yep.
[51:10] (external link, opens in new tab) >> Where does this all start? Is it you add stone? >> No. So this is this would be like more a level above the just adding the stone. It would be more where the player adds the stone where does adding the stone and it also does checks. Right. So you want to add a stone to you want some kind of well so you what I'm trying to understand is
[51:45] (external link, opens in new tab) Do you you can still add a stone to the board and then have like a an attached engine to the board that does all the thinking for you or you can initialize an engine >> with the board. It doesn't really matter, >> right? >> But you you're saying that the the the logic should be in a separate place. >> Yeah. >> What I'm saying is for now make the logic in the board and we can extract it later. >> Okay. That that would make it simple. >> Simplest thing that would work.
[52:17] (external link, opens in new tab) >> Okay. You're right. So it would make it part of the add stone >> for now if you want. Yeah. >> For now. Last thing scenario is eliminate liberties or how how would you say I don't you just surround something? Yeah, that sounds nicer. around
[52:48] (external link, opens in new tab) Opposite color stone. Maybe here remove What do you think? >> Does it get removed or does it get replaced? >> It gets removed. >> So it becomes empty. >> Becomes empty. >> Okay. So,
[53:21] (external link, opens in new tab) So we did a make for and what was the nice shortcut that you did? Ctrl AltV to extract a variable V. Very cool. So, this Oh, this is also part of the setup. So do that. So let's put it in the middle. So
[54:14] (external link, opens in new tab) You can just press Ctrl + D to duplicate a line, by the way. >> Oh, really? >> Try it. That's just let me try that. >> Oh, very cool. Very cool. >> And then you don't lose whatever is in your copy buffer. >> Oh, wow. That's even cooler. That is very cool. Okay. And then the action would be
[54:47] (external link, opens in new tab) >> So that's the top row. >> So this this would be the action that finally does the removing. >> But doesn't stone have nine blocks to fill around it? No, you only need the the how you horizontal and vertical diagonals you do not need. >> Okay. >> Mhm. >> All right. So, let's see.
[55:18] (external link, opens in new tab) Okay. I would write this test a bit more clearer where the position of one two three two one to be left position right position bottom position for example >> okay see what I mean >> I'm trying to figure out how I would I add a comment to indicate that or would I >> well just the just the just the X part or the part the other part
[55:50] (external link, opens in new tab) Maybe a comment I'm not sure. >> So, you mean like bottom? >> yeah. >> Well, actually this one would be this one would be left X, left Y. Is is this what you mean? Well, just the one that may that that tells me when I that I visually can see where would it be? What if we just put the lines visually around
[56:21] (external link, opens in new tab) Can you make one line more to the left? One one line more to the right. One line. See what I mean? We can actually position the C code so that we visually see which line is above or to the right of which line. >> Okay, that's that's interesting. >> I want the test to be almost visual. >> Wow. Okay, that's an interesting concept. >> Kind of like this. >> Yep.
[56:55] (external link, opens in new tab) That's very interesting. Just above it. Yep. Oh, that did not work. >> Yeah. >> Wow. This looks pretty cool. >> It is very cool. I agree. Okay. So now I can actually scroll as a reader of the test. I can scroll and I can see that this last one seals the deal.
[57:30] (external link, opens in new tab) >> Yeah. >> Okay. >> This does this definitely does make it more readable. Very interesting. >> All right. >> Readability (external link, opens in new tab) is one of the most important things in the test because the these tests assuming it's a real software they have to last for 10 years. >> Mhm. Five years from now, someone's going to read your test, they're going to see this. >> Okay. >> So, readability is really important. And it also helps you figure out that you're in the right track with the numbers,
[58:02] (external link, opens in new tab) That your test isn't wrong. variable just before the semicolon. >> Control alt v. >> Control >> alt v alt >> v >> alt v. Yeah. For variable. >> Okay. All right.
[58:45] (external link, opens in new tab) I don't know how it gained the double parenthesis. Now make it compile. We We're missing the white, right? Okay, let's see what happens obviously. Okay, now I think that to make this possible,
[59:17] (external link, opens in new tab) We have to start adding more information to each each area, right? Not just position status, >> but the position status and the color, >> right? which to me represents a stone >> in a way. >> Mhm. >> No, >> you're right. >> or just a structure, whatever you want. But now we have to make this passable in the simplest ways possible. So let's see let's see what we can do.
[59:48] (external link, opens in new tab) Let's go to the production code. Okay. Okay. I'm going to I'm going to pause this for a second. I'm going to take a little break. And I'll be right back. >> Okay, >> we're back. >> All right. So like you mentioned we had to put in more information but the interesting thing is that if we do the same thing we did with the position status matrix is that
[1:00:23] (external link, opens in new tab) >> checking like if we initialize another matrix for the stone color is all everything is going to be set as one color initially right >> interesting. Yep. >> But since it's empty, we don't care about it, >> right? So, we don't care about that right now. So, we just just go ahead and do it first. >> Well, we can do another So, you're saying just create another matrix. Why don't we just put different an object with more information in the matrix itself,
[1:00:58] (external link, opens in new tab) >> right? So, create or create a mat you may create a matrix of a different kind of object, a more object with more information, right? >> Yeah. Instead of instead of position status, >> we can create a matrix of stone info or something. >> Okay. >> What do you think? >> Right. So, I think that's a good idea. I think that that's a good idea to head to. So, would would I start doing that right now? >> Well, there is no right way. We we can start doing that right now.
[1:01:28] (external link, opens in new tab) Remember, the point is to make the current test and all the other tests fail in the simplest way possible. So we have to make as many assumptions as we can so that we don't forget to to add those tests later. Whatever if we if we put in too many if we remove too many assumptions if we make the code too generic we might not feel any need to write tests for it later. >> Yeah. But I mean like right now one of the tests is failing. Should so should we take that out refactor the code and bring it back?
[1:02:00] (external link, opens in new tab) No, no, no. We have to make everything pass because we have to the the fact that the test is failing gives us focus. >> Okay. >> Okay. It tells us exactly what we're trying to to achieve. >> So we we have to make the the point is here to make the all the tests pass. It's not to refactor, it's to make all the tests pass. >> Okay. >> So whatever we have to do, we have to do. If we have to change the internal board, we can do that. >> Okay. Well, we can do many other things.
[1:02:30] (external link, opens in new tab) I mean, we can have an an extra board internally. Whatever you want. >> All right. Well, I think the easiest way to first make it pass is to make not replace the object, replace it with the object, but copy and make it the stone color matrix. >> Okay.
[1:03:01] (external link, opens in new tab) But instead of position status, it takes in the stone color. >> Sure. so then add stone position. The best best way to do it for now would be
[1:03:34] (external link, opens in new tab) Just add another line I guess. >> Right. >> Just duplicate it and then change it to some color. Right. >> You forgot to use control D, my friend. Oh, >> I'm not saying that's the only way, but it's a good tactic. >> It is. I agree. But that's not be enough to make that test pass.
[1:04:04] (external link, opens in new tab) >> No, because get positions. Well, no. This is where we just have to add the the calculation. Let's just add the calculation right here in the ugliest way possible. It doesn't have to be ugly, but in the just just do it here. We can refactor it later. >> Okay. >> So now just figure out if some if if the if there is if the stone on the board and we know which stone it is. Right. >> Right. >> Let's figure out if that stone is is surrounded.
[1:04:35] (external link, opens in new tab) >> Okay. So just using hard-coded values. >> Yeah. That's an assumption we can make and then later we can say aha what if it's a different stone? Okay. >> So making the assumption will make it easier for us to figure out the algorithm. Then we can later make it more generic. That's the point as well. Just just figure out for this test and all the others. Okay. So the simplest would be it's going to be interesting.
[1:05:29] (external link, opens in new tab) No, the end should be Yeah, sure. >> Say again. >> No, no, I'm just I'm just blabbing away. >> Yeah, I think you're on the right track. All right. You forgot to do an equals equals just before.
[1:06:15] (external link, opens in new tab) >> Yeah, actually you ReSharper can help you out with that. >> Oh, really? >> You see the the the pencil there? If you put >> split, flip. Let's see what happens to split. >> no. >> That looks dis that looks disgusting. >> Okay, never mind. Forget I said anything. >> Maybe it's cuz I didn't complete it yet. But
[1:06:54] (external link, opens in new tab) What's the stone location? Two and two. >> Yeah. >> Awesome. Yep. Awesome. >> Okay. But >> that doesn't make any sense. We have Yeah. Yeah. Actually, it does make sense. I guess >> I think the the problem is that the initial position is probably all white or no, is it all black? >> No, it's all white. You're right. You're right. >> You know what's cool
[1:07:26] (external link, opens in new tab) Is that I think at some point we can just get rid of the other matrix. >> Yeah, at some point >> I think actually a couple of tests from now. I mean we don't have to do anything with the other position matrix if we can just check the color of the stone color. >> Isn't that cool? >> Yeah. >> Cool. Okay. So we made all the tests pass, right? >> Right. Obviously not great because it's not readable, not maintainable, but we can at least go ahead now and say, okay, let's just Oh, you have the control and set to something else, right?
[1:08:07] (external link, opens in new tab) >> No, let me >> hold on. >> Control. No, yeah. Yeah. >> W I can't work with this. Never mind. So what I want is to select the whole thing. Say okay. Ctrl Alt M extract methods. Ctrl Alt M.
[1:08:38] (external link, opens in new tab) >> It's not how it right now. >> H. >> Oh yeah. Control Alt M. >> Caps lock. >> I tried with the caps lock. Okay. Just extract method. Good. >>. >> What happens when you have keys bound to anything else? Just press just undo. Undo. If I can't use control, I can't do anything on your machine, dude. >> Let me let me just move the script.
[1:09:11] (external link, opens in new tab) There you go. Okay, let's see if I can do something now. Ctrl AltM. Yay. Extract method name. Let's what do you what would you call this whole thing? >> let's call it check. Check neighbors. >> Check. >> Checking. It's not just checking. >> it's actually removing >> right. So removed surrounded stone.
[1:09:43] (external link, opens in new tab) >> Okay. remove surrounded stone. Cool. Now we can go ahead and say surrounded stone. Let's see. We didn't break anything. Alt R. Okay. Now let's write another test that proves that other stones can be surrounded as well. I think we're getting somewhere.
[1:10:14] (external link, opens in new tab) Okay, >> we can make this a >> sorry, >> you want to reuse that test. >> do you know how to reuse tests? >> Right. The test case. >> Exactly. >> okay. So, let's have you used test case before? >> Yes. >> Okay. The difference is that this time in our test case
[1:10:46] (external link, opens in new tab) >> we have to calculate the neighbors. >> No, we don't I don't want us to calculate anything cuz we could have a bug and when you're calculating things in the test >> most likely you're also repeating production code and if you get the calculation wrong you actually creating the bug and then the test will pass. So, we would have to list out the X and Y for all the neighbors, too. >> Yep, I guess so. >> Okay. >> Okay. So, the way I would do it first is to say
[1:11:17] (external link, opens in new tab) Just go through each of them one by one and say, I'm trying to see maybe we should just write another test. I think it will be more more readable. >> Okay. >> then then stuffing the whole >> That's probably the easiest way to do it. >> Yeah. >> Oh, properties. God, so many windows. Start using Vim and less windows in Vim. Control V.
[1:11:48] (external link, opens in new tab) Color stone 2. And here we're just going to change just figure out give me a different one position. I want to be able to see the difference between these two tests so that everything is just one off. Maybe just one line below. >> Are you What do you mean one off? Just change like a two to threes. >> Well, change all the y's to plus one. I'm guessing that that's all we need. Right.
[1:12:19] (external link, opens in new tab) >> Right. So, we would say this is a two, this is a three, and this is a four. Right. >> Right. >> And this is still >> that would be a three. >> And we can see them cuz they're right next to each other. So, it shouldn't be a problem. I can figure it out. >> and then we have a 2x3. >> Yes. Alt R.
[1:12:51] (external link, opens in new tab) >> Okay. >> Or Okay. So now here's the cool thing. We get to go to the production code and just make it a bit more generic. Remove some of the assumptions. So we can say just get get this as a parameter. So I can say Ctrl AltP for it parameter. replace. Yeah, we can use six. Six occurrences. >> No, just one occurrence for now.
[1:13:23] (external link, opens in new tab) >> Yeah. >> X. >> Yes. >> and control P for Y. And now everything else is just a calculation. Right. >> Right. So it will be faster if you just do all the cuz I'm doing it remotely. If you just make all the differences
[1:14:24] (external link, opens in new tab) Whoops. We got a bug. All right. We need to change this to Y. But this still this is also still going to fail. And then it's supposed to be check all the neighbors. Actually, it's probably going to be more. >> Wait, hold on. What? >> Well, it's because >> Are you just renaming it? >> No, I'm not going to rename it. I was going to control D. Shoot. I was going to control D.
[1:14:59] (external link, opens in new tab) Oh, this is really really really ugly code. >> Don't worry, just make it work. We ju we do we really have to use all of these. >> >> we just have to figure out just check specific stone, don't we? >> Right. >> Just 2 by two or 2x3 or Oh, we have to make it work for both. Right. >> Interesting.
[1:15:30] (external link, opens in new tab) But we still have a bug. >> Yeah. Yeah. >> X - one, X + 1, Y - 1, and Y + 1. We didn't check the Y and X itself.
[1:16:13] (external link, opens in new tab) What do you think? We can also debug if you want to. >> let's let's go with how do how do you debug with the Okay. So, you basically put a break point and then you go to the specific test. Actually, what I'm going to do, I think we have a way to to see multiple windows in Visual Studio at the same time, right? >> Yes. >> you split it, right?
[1:16:45] (external link, opens in new tab) >> Yeah. >> vertical. I want vertical one. New vertical tab group. Okay. >> The thing is I don't know if it opens the same file in >> Oh, that sucks. Never mind. Okay. But we still want to go to the test.
[1:17:16] (external link, opens in new tab) We can close this maybe so we get a bit more view. Ah let's see. So you can go to this test and say test with right click on it. Test with debugger. >> Nice. Okay. Cool. >> Cool. >> Okay. But remember we if we want to debug a specific breakpoint
[1:17:50] (external link, opens in new tab) >> Mhm. Then we could just move forward until the fifth one or the middle one. >> fifth one or oh the middle one, right? >> So I want to I I want to do something specific. I mean if we look at the specific test by the way I'm pretty sure we don't have to do everything. We always have to check just the one above. >> I mean it's always we have to check with this one. >> We only have to check this one. Right. >> Right. So we can always check the one with x and y minus one,
[1:18:24] (external link, opens in new tab) >> right? >> So that should be sufficient, >> So I'm maybe the the test I mean the maybe the production code is wrong. If we look at the >> we can make it simpler. >> Yeah, I mean let's maybe we're just getting the whole thing wrong. Simplify. Okay. I mean what if we just remove surrounding with x and y minus one. >> Okay. >> I we already have that
[1:18:56] (external link, opens in new tab) But we we know that this one is supposed to work. Right. >> Right. >> And we we only have to do it on this specific thing. We don't have to break here. Actually, we do. What we don't have to do it another break point here. So now we can if we just run this test
[1:19:35] (external link, opens in new tab) It actually passes. Interesting interesting >> maybe we don't need to debug at all. Yeah. Five pass. You see that? >> I don't know how that does anything, but >> Oh, well, welcome to programming. Right. >> Right. >> Okay. So, we know >> I know why. Why? >> Actually, no. I don't know why. >> But that's the cool thing is that because we can make assumptions, we can make small strides towards something. Now obviously we know that we're missing checking the other things because if we add things in the different order.
[1:20:10] (external link, opens in new tab) >> Yeah. >> Right. >> It won't work. So now we get to write a test that proves that if you add things in a different order stone add stone let's say above >> okay >> above and surround opposite color stone remove opposite color stone How's that?
[1:20:43] (external link, opens in new tab) >> Right. >> So now we can simply change the visual markup of the test to say aha. But now we can't write the test in a visual way. How's that? >> Yeah, it doesn't look as pretty. >> Yeah, but we we can still do it in at least Ctrl X. >> We can do is Yeah. Remove the top one and add it. >> And then say >> in another line below. >> Yeah.
[1:21:17] (external link, opens in new tab) I don't know why to remove the whole panel. >> It's possibly because the line above it. Yeah. Okay. Okay. So now we can see 1 2 3 four and this is the fifth. >> And now running all the tests. Alt R should one of them should fail. >> Right. >> Five passed, one failed. And now we can just go and and
[1:21:48] (external link, opens in new tab) Slowly but surely add just one more check. Right. >> Right. >> Ctrl + D. Add a Y + one. Right. >> Let's see what happens. Alt R. Yeah. Okay. You want to try the next two ones? >> I still I still don't understand why the other one did not pass. >> you know, we're human. We will never understand.
[1:22:18] (external link, opens in new tab) We can only just assume that we're stupid and then do things simpler. >> So, would it make sense to just exhaust all the options? >> We We don't have many. We just have four, right? >> I mean, yeah, like the other two options. We have to we have to have other because each one of them is basically a feature in the application. Right. >> Right. Right. >> Sounds like you have a clicky keyboard. Are you using like a DOS keyboard or something?
[1:22:48] (external link, opens in new tab) >> I have a mechanical keyboard. Yes. >> Okay. >> So, now we're adding one to the left. Left. Okay. As left and surround. Okay. So, let's add this back. >> Now, when Visual Studio, you don't have to make a selection. If you just want to cut the whole line, you can just press Ctrl X with no selection. It will cut the whole line. >> Oh, really? >> Yeah. >> And Ctrl + C works the same way, but you should add it to the middle.
[1:23:21] (external link, opens in new tab) Remember, >> more to the You should tap that line a bit. >> Well, actually if we move this move this guy. >> Yeah, but I want them people to see that there is an empty space there. >> Okay. >> And where's the one to the right? Oh, yeah. Now it is now. Okay. Because then I had to ask, hey, where's the one to the right?
[1:23:55] (external link, opens in new tab) >> Okay. That's such a huge gap in the >> Yeah, exactly. I mean, I can see that there's above, below, and to the right. And that makes me wonder, maybe this is the one to the left. >> Yeah. >> Okay. Run all the tests. >> Okay, one failed. >> Let's go ahead and control D. All right, >> perfect. One to the left. Should do that.
[1:24:26] (external link, opens in new tab) R. >> All right. Okay. >> Now, now it failed. >> Now we know where, now we've learned something. >> >> index outside the bounds of the array. >> There you go. >> Now we can go and fix I think it's the 19 thing, isn't it? >> you want to debug it or do you know where it's coming from? >> Yeah, let's debug it.
[1:24:56] (external link, opens in new tab) This is probably this. >> But you have to debug from the test. Remember this, >> right? >> so it's better if you put the breakpoint in the test and not in the production because otherwise you're going to get there every time for each. >> Oh, so you were just going to run the whole test. I see. >> is this how you do it? >> This is the ReSharper test runner (external link, opens in new tab). You can do it that way as well, but you have to put a break point somewhere.
[1:25:28] (external link, opens in new tab) >> So, where is your your break point, >> right? >> It's right here. Okay. >> Remove it was at >> here. Add right. Right. Right there. Okay. Okay. >> Right. >> Okay. Then debug the debug that bastard. Right. Just do you is there a shortcut >> test with debugger? Well, we can make a shortcut if you want.
[1:25:59] (external link, opens in new tab) >> Do that later. I just want to get this.
[1:26:33] (external link, opens in new tab) X is zero when y is three. x is zero. Who's so we have an x which is a zero. cuz x - one is a zero. >> Wow. >> Mhm. >> Okay. So, do you understand the bug? >> A little bit though. The X react position though. How do we go? Is there a way? I'm not too familiar with
[1:27:04] (external link, opens in new tab) Visual Studio Debugger. Is there a way to back out to history or do I have to rerun the test? Well, you can go you can see here in the call stack you can go to where you to the location of how we got here. >> So you can see that this is X. It was one. >> I see. >> Okay. >> Mhm. And then so maybe I can go even higher in the call stack. >> Mhm. So we had a one and a three because we had a two,
[1:27:37] (external link, opens in new tab) >> right? >> So Okay. So our bug is that if we are if we we don't have to check anything that's lower than zero. That's our bug. Right. >> Right. >> Okay. >> Right. That's our bug. >> Right. Right. So how do we make this pretty? >> Well, we don't have to check remove surrounded stone. Yeah, we do have to check if we move around the stone, but only if x.
[1:28:08] (external link, opens in new tab) Well, we for each of these ifs, we actually have to check if we are lower than zero or not. >> Right. >> Or we can also just you know what the simplest thing would be to just catch all the errors. Catch an index out of ringer. >> All right. That's interesting. But That's cool.
[1:28:49] (external link, opens in new tab) I never seen it used that way, but that's very that's very cool. >> The the point here is to deliver, right? If ever this becomes a problem, because sometimes, you know, it's the performance thing, we can do something about it. But usually that's not a problem for go games at least where people think for hours. >> Okay, run all the tests. But alt R won't run. It will just repeat the last action. So you have to go to the project and run all the tests or just outside the test just run all the projects.
[1:29:26] (external link, opens in new tab) >> So to run tests >> run all the tests. So you can click outside the test run test. Okay. >> Oh, still one fail. >> Interesting. >> Well, we had other failed other Yeah, there's not an out exception. >> Oh, okay. Talking myself. Let's see. >> Aha. So, it's it's not good enough. Mhm. >> So the the way I think about it is that we get an index out of range exception,
[1:29:58] (external link, opens in new tab) But we still need to make it an empty position. So >> ah you're right. >> So we only we have for each of these ifs we actually have to check if x is I mean only for the ones where x is smaller than y than zero. For now we can just check smaller than zero and then we can check for all the others or you can just say is x yeah we basically have to do each if if check is it it's possible.
[1:30:31] (external link, opens in new tab) Is there a way for an array to check if it's allowed to use a specific instance instead of checking if there is the size of x or y? I'm not aware of any. >> then I guess it would be here. Sorry. So here we would say if
[1:31:01] (external link, opens in new tab) X is smaller than two actually it's bigger than one then one and right but that wouldn't work because then for each x where it's actually not bigger then we will always have a false here >> right >> aha so that's not good enough >> so we have to have a separate if for each one agreed
[1:31:34] (external link, opens in new tab) >> at least for now so we can say if and my swamp stone color. This can we change it to an ore? I guess.
[1:32:04] (external link, opens in new tab) >> No, that's not going to work. I think we might need a break we might need to break up the if statement. Yeah, just >> then >> Okay, so if x is bigger than one and y well if x is bigger than one then we can do all the checks for x is bigger than one. How's that? >> Right. >> H >> right. Yes. one then we can do
[1:32:37] (external link, opens in new tab) What do you think if let's see x - one oh maybe we can just use it as flags right so we can say and equals matrix then surrounded on left
[1:33:09] (external link, opens in new tab) Equals equals true. It's bigger than one. And then we can say else surrounded on left equals true. Right. >> Yes. So if x is on the left vertice then it's surrounded on the left. >> Right? >> We can make it nicer later, >> right?
[1:33:41] (external link, opens in new tab) So you can do that for each of the sides, >> I guess. So what do you think? >> I I agree. You could take it out of the try statement, too, then. >> Sure. Let's get rid of the try.
[1:34:12] (external link, opens in new tab) It would just be each of the positions in the end. So left surrounded and right surrounded and >> yep surrounded on left and surrounded on right on right and surrounded on top and surrounded on
[1:34:42] (external link, opens in new tab) Bottom. Right. >> Yep. You need a parenthesis. So, yep. >> Okay. So I guess we know where we're heading. >> So, we need to repeat that. >> Yeah. You want to try it? I think it will be faster if you do it on your end. >> All right. >> And I think Yeah. And we also have to check for color white. So, that's true. Yeah. So, we And you know what? We could make this into a method later, but let's just make it all happen right here, >> right?
[1:35:18] (external link, opens in new tab) >> Just duplicate, dude. You're copy pasting like crazy. >> You want me You want me to do a control D instead? >> Oh, next time. This is very out of habit. So this would be less than 90.
[1:35:48] (external link, opens in new tab) This would be plus y is greater than one. >> You have to make it surrounded on the right also. >> Yeah. on this one. So let's try it on. >> We don't have to do the smaller than 19. Actually, we don't have any test for it anyway, >> right?
[1:36:21] (external link, opens in new tab) So you want to just get rid of it then.
[1:37:15] (external link, opens in new tab) Then you can just declare each one surround rounded on bottom is equals true but only if right if stone color basically you can just declare this right just change this surrounded on top equals >> right >> stone color matrix wait right wait Okay.
[1:38:02] (external link, opens in new tab) What is this? Oh, >> maybe a try catch thing. Just remove one. still showing of course cuz we're not done yet. We're not done yet because let's see remove the stone. We have this for false surrounded on bottom. It cannot always be false. It has to be true at some point, right?
[1:38:33] (external link, opens in new tab) We're missing another one. Just the last one. Crl + C. The only one we care about that we actually calculate for X is on the left. So it's on bottom if it's X + one. Actually, no, it's X and Y + one. And surround on top is X - one with Y. No see y minus one
[1:39:09] (external link, opens in new tab) >> this is basically what we had >> right >> so we're only on right now if x is bigger than one >> we have >> we have true and else surrounded on left is true by default let's see At least we have to test to know. >> I think it this supposed to be a zero right there. Same thing with here.
[1:39:42] (external link, opens in new tab) >> Oh, okay. H never mind. It's dead. >> It's dead. Huh. Now, this is where source control would back up and we would just undo until we had that one failing test again. >> Yeah. >> Let's see. Okay. Let's try again. We have the surrounded one. Let's just do the whole thing here again. So, we can go back to where we had some kind of surrounded on left is x
[1:40:16] (external link, opens in new tab) Minus one and y. And then we just just get rid of the whole thing. And this is almost where we were, right? Right. >> Alt R should have just one failing test. >> Right. But with the indic to empty position position is filled. Yeah, that's the index hand. Now we have to check just check this.
[1:40:46] (external link, opens in new tab) So we can say surrounded on left equals x= z. >> Yeah. or >> or this is white. Let's see. All right. So, same thing with the >> same thing with the yus one surrounded on top. So, y equals z. >> So, because we still have index out other out of balance, right?
[1:41:20] (external link, opens in new tab) >> Yeah. But it's not about the other things. You think it's the other things? I mean it's oh it's the same test but we have four failing tests. So is the to empty position other empty is that affect >> I think it's this part right here if you add the y equals z same thing that you did before. >> Sure.
[1:41:55] (external link, opens in new tab) >> All right. Only one fail this time. left and surround that doesn't make sense because left would have worked. Empty position filled position. So it's either x is zero surrounded on right should be okay surround on bottom should be okay. So what the hell happened? >> So this one we can probably debug. >> Okay. >> But I need debug. So is this the same test that we're is failing? >> You just look at the name >> right
[1:42:27] (external link, opens in new tab) >> you can see the name here Edstone left >> okay I'm just going to remove this. Okay. Which one is the same? Actually, I don't know if it's this one.
[1:43:11] (external link, opens in new tab) So, it's supposed to say true, true, and then the bottom one, but still false. So, how is the bottom one still false? >> Well, it just returned false. So, let's do >> is our test wrong? X Y + 1 is stone color white. Interesting. So, the bottom is X and Y + one, right? If we go to the test,
[1:43:42] (external link, opens in new tab) This is our test. We have this is the black stone. This is the right. This is the top. This is the bottom. >> Oh, this. No, actually not. >> H. Yeah, this is one. It should be on the left. It should be two. The test is wrong. You agree? >> No. Like because xus one.
[1:44:14] (external link, opens in new tab) >> Oh, yeah. Oh, yeah. So sorry, my mistake. So it is one. Okay. And we're then we're checking the left of each and every one of them, but we're not checking the actual one. So maybe that's our bug, right? Cuz here we're checking for X and Y, but we're checking all around them, but we're not checking X and Y itself. >> Okay? >> We're not checking to the right of it. That's what I'm saying. We're not checking X + one. >> Oh.
[1:44:45] (external link, opens in new tab) Oh, you're right. You're right. >> So, we're missing a check for x + one. let's go to control alt l for solution. Oh, nothing. Interesting. run all the tests.
[1:45:22] (external link, opens in new tab) >> Nice. >> Okay, so we're getting there slowly but surely. >> All right. >> so we have a test for the left. >> We have a test for >> Go ahead and still add one for the right even >> we know it's going to pass. >> You You think it's going to pass? >> I think it's going to pass. >> Then let's make it fail first. Then we have we've added too much. >> Why do you think it's gonna it's gonna pass? >> Right. >> What assumption did we not add? >> It make something do generic.
[1:45:54] (external link, opens in new tab) >> So this one we added in that did not affect the previous test. I did make the other test pass. So if I comment this one out and I add the right version, it'll first run all the tests. >> Okay. Right. Okay. Can we remove anything else by the way? Just to see what happens. Right. Okay.
[1:46:27] (external link, opens in new tab) So, you can see I'm just checking our coverage (external link, opens in new tab) a bit. See what happens. Okay. So, we definitely don't need the line there. >> Yeah. So, we need another test. True. Good. Good catch. Oops. How did that happen? Control D work with this. >> Yeah, it works with everything. Nice.
[1:47:15] (external link, opens in new tab) To the paste. Oops. What did I just do? >> Yeah, you just push the line to the right. That's okay. Just >> Okay. >> See? >> Okay. Now add the one to the right. >> Fail. >> Okay. On on comment should pass.
[1:47:47] (external link, opens in new tab) >> Should pass. Sweet. >> Okay. Okay. >> Okay. >> So, now we're getting somewhere, I guess. Let's see. So, now >> we got to refactor, right? >> We got to refactor. Well, remove stone at this place and that place and this place. What do we Here is where we just just extract another method and say control M remove
[1:48:30] (external link, opens in new tab) Surrounded. Okay. Check stones around position and remove if needed. How's that? >> Yeah, I like I like the last part. >> Stone check. Stoned. Is anyone stoned around this position? >> and then we have, let's see, alt R just to make sure.
[1:49:04] (external link, opens in new tab) Now, do we really need the position status matrix anyway? >> The pos >> I don't think so. We can just check if it's filled by getting the stone color. >> Well, the stone only has two values, right? Stone color matrix only has two values, right? >> Yeah, but it could be null. If it's null, you can just say that it's not filled, right? >> Oh, will it be null? It's a good thing to try then >> return
[1:49:37] (external link, opens in new tab) So we can say if position status of control V is stone color matrix >> yeah we just have to replace the stone color matrix. Yeah. >> Return control shift space. Does it give me anything? Yeah. Position status empty. >> Right. >> Otherwise just return
[1:50:16] (external link, opens in new tab) Position status. Control shift space. No. Return. Nope. Nothing. Return status filled. That's it. >> All right. Give it a try. >> Oh, why does it say that this will never get executed? Interesting. >> It's because I'm pretty sure in an array it >> treats the enum value zero. It sets it to zero and one of them is probably set to zero which is black. >> So we can make it the nullable type. >> Okay.
[1:50:48] (external link, opens in new tab) >> Like this, right? >> Oh yeah, you write something something like that. Okay, there we go. Let's see. Empty position but but failed. Yeah, we just have to change the test, I guess. No, what happened? Let's see. Rar equal empty position status. What did I return?
[1:51:19] (external link, opens in new tab) Failed. Stone color matrix. Is there anything? It's nullable. Ergo. Yeah, whatever. So, I'm guessing it returns field all the time. >> Let's see again.
[1:51:49] (external link, opens in new tab) >> What was the error again? except empty but was failed. It's never null. We can just if this value I guess equals null. Oh no. The value can never be null. We can just say
[1:52:21] (external link, opens in new tab) Is no I think no >> if I has value I think is the is >> yeah true I agree
[1:53:00] (external link, opens in new tab) Interesting. So when you fill out an array with nullables, you still get non-nullables. Interesting. I guess we can just go back to where we were. I don't care about that. Let's see. Okay. We do control Y. Okay. Let's see. We back to where we were. Okay.
[1:53:31] (external link, opens in new tab) Okay. Let's see. I'm going to stop here. We're going to do another one.