fix: bouncing ball exercises
This commit is contained in:
		
							
								
								
									
										119
									
								
								18-project-bouncing-ball/exercises/01-find-the-bug/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								18-project-bouncing-ball/exercises/01-find-the-bug/main.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,119 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/inancgumus/screen" | ||||
| ) | ||||
|  | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: Find the Bug | ||||
| // | ||||
| //  As I've annotated in the lectures, there is a bug | ||||
| //  in this code. Please find the bug and fix it. | ||||
| // | ||||
| // | ||||
| // HINT #1 | ||||
| // | ||||
| //  💀 Read this only if you get stuck. | ||||
| // | ||||
| //  Print the width*height and the capacity of the drawing buffer | ||||
| //  after a single drawing loop ends. You might be surprised. | ||||
| // | ||||
| // | ||||
| // HINT #2 | ||||
| // | ||||
| //  💀 Read this only if you get stuck. | ||||
| // | ||||
| //  The bug is in the drawing buffer. It doesn't include the | ||||
| //  newline and space characters when creating the buffer. So | ||||
| //  the buffer is not large enough to hold all the characters. | ||||
| //  So new backing arrays are getting allocated. | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
|  | ||||
| func main() { | ||||
| 	const ( | ||||
| 		width  = 50 | ||||
| 		height = 10 | ||||
|  | ||||
| 		cellEmpty = ' ' | ||||
| 		cellBall  = '⚾' | ||||
|  | ||||
| 		maxFrames = 1200 | ||||
| 		speed     = time.Second / 20 | ||||
| 	) | ||||
|  | ||||
| 	var ( | ||||
| 		px, py int    // ball position | ||||
| 		vx, vy = 1, 1 // velocities | ||||
|  | ||||
| 		cell rune // current cell (for caching) | ||||
| 	) | ||||
|  | ||||
| 	// create the board | ||||
| 	board := make([][]bool, width) | ||||
| 	for column := range board { | ||||
| 		board[column] = make([]bool, height) | ||||
| 	} | ||||
|  | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
|  | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
|  | ||||
| 	for i := 0; i < maxFrames; i++ { | ||||
| 		// calculate the next ball position | ||||
| 		px += vx | ||||
| 		py += vy | ||||
|  | ||||
| 		// when the ball hits a border reverse its direction | ||||
| 		if px <= 0 || px >= width-1 { | ||||
| 			vx *= -1 | ||||
| 		} | ||||
| 		if py <= 0 || py >= height-1 { | ||||
| 			vy *= -1 | ||||
| 		} | ||||
|  | ||||
| 		// remove the previous ball | ||||
| 		for y := range board[0] { | ||||
| 			for x := range board { | ||||
| 				board[x][y] = false | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// put the new ball | ||||
| 		board[px][py] = true | ||||
|  | ||||
| 		// rewind the buffer (allow appending from the beginning) | ||||
| 		buf = buf[:0] | ||||
|  | ||||
| 		// draw the board into the buffer | ||||
| 		for y := range board[0] { | ||||
| 			for x := range board { | ||||
| 				cell = cellEmpty | ||||
| 				if board[x][y] { | ||||
| 					cell = cellBall | ||||
| 				} | ||||
| 				buf = append(buf, cell, ' ') | ||||
| 			} | ||||
| 			buf = append(buf, '\n') | ||||
| 		} | ||||
|  | ||||
| 		// print the buffer | ||||
| 		screen.MoveTopLeft() | ||||
| 		fmt.Print(string(buf)) | ||||
|  | ||||
| 		// slow down the animation | ||||
| 		time.Sleep(speed) | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,99 @@ | ||||
| // For more tutorials: https://blog.learngoprogramming.com | ||||
| // | ||||
| // Copyright © 2018 Inanc Gumus | ||||
| // Learn Go Programming Course | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
|  | ||||
| package main | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/inancgumus/screen" | ||||
| ) | ||||
|  | ||||
| func main() { | ||||
| 	const ( | ||||
| 		width  = 50 | ||||
| 		height = 10 | ||||
|  | ||||
| 		cellEmpty = ' ' | ||||
| 		cellBall  = '⚾' | ||||
|  | ||||
| 		maxFrames = 1200 | ||||
| 		speed     = time.Second / 20 | ||||
|  | ||||
| 		// drawing buffer length | ||||
| 		// *2 for extra spaces | ||||
| 		// +1 for newlines | ||||
| 		bufLen = (width*2 + 1) * height | ||||
| 	) | ||||
|  | ||||
| 	var ( | ||||
| 		px, py int    // ball position | ||||
| 		vx, vy = 1, 1 // velocities | ||||
|  | ||||
| 		cell rune // current cell (for caching) | ||||
| 	) | ||||
|  | ||||
| 	// create the board | ||||
| 	board := make([][]bool, width) | ||||
| 	for column := range board { | ||||
| 		board[column] = make([]bool, height) | ||||
| 	} | ||||
|  | ||||
| 	// create a drawing buffer | ||||
| 	// BUG FIXED! | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
|  | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
|  | ||||
| 	for i := 0; i < maxFrames; i++ { | ||||
| 		// calculate the next ball position | ||||
| 		px += vx | ||||
| 		py += vy | ||||
|  | ||||
| 		// when the ball hits a border reverse its direction | ||||
| 		if px <= 0 || px >= width-1 { | ||||
| 			vx *= -1 | ||||
| 		} | ||||
| 		if py <= 0 || py >= height-1 { | ||||
| 			vy *= -1 | ||||
| 		} | ||||
|  | ||||
| 		// remove the previous ball | ||||
| 		for y := range board[0] { | ||||
| 			for x := range board { | ||||
| 				board[x][y] = false | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		// put the new ball | ||||
| 		board[px][py] = true | ||||
|  | ||||
| 		// rewind the buffer (allow appending from the beginning) | ||||
| 		buf = buf[:0] | ||||
|  | ||||
| 		// draw the board into the buffer | ||||
| 		for y := range board[0] { | ||||
| 			for x := range board { | ||||
| 				cell = cellEmpty | ||||
| 				if board[x][y] { | ||||
| 					cell = cellBall | ||||
| 				} | ||||
| 				buf = append(buf, cell, ' ') | ||||
| 			} | ||||
| 			buf = append(buf, '\n') | ||||
| 		} | ||||
|  | ||||
| 		// print the buffer | ||||
| 		screen.MoveTopLeft() | ||||
| 		fmt.Print(string(buf)) | ||||
|  | ||||
| 		// slow down the animation | ||||
| 		time.Sleep(speed) | ||||
| 	} | ||||
| } | ||||
| @@ -5,6 +5,15 @@ | ||||
| // License: https://creativecommons.org/licenses/by-nc-sa/4.0/ | ||||
| // | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/inancgumus/screen" | ||||
| ) | ||||
| 
 | ||||
| // --------------------------------------------------------- | ||||
| // EXERCISE: Adjust the width and height automatically | ||||
| // | ||||
| @@ -88,15 +97,6 @@ | ||||
| // | ||||
| // --------------------------------------------------------- | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/inancgumus/screen" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	const ( | ||||
| 		width  = 50 | ||||
| @@ -107,6 +107,12 @@ func main() { | ||||
| 
 | ||||
| 		maxFrames = 1200 | ||||
| 		speed     = time.Second / 20 | ||||
| 
 | ||||
| 		// drawing buffer length | ||||
| 		// | ||||
| 		// *2 for extra spaces | ||||
| 		// +1 for newlines | ||||
| 		bufLen = (width*2 + 1) * height | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| @@ -123,7 +129,7 @@ func main() { | ||||
| 	} | ||||
| 
 | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
| 
 | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
| @@ -57,8 +57,13 @@ func main() { | ||||
| 		board[column] = make([]bool, height) | ||||
| 	} | ||||
| 
 | ||||
| 	// drawing buffer length | ||||
| 	// *2 for extra spaces | ||||
| 	// +1 for newlines | ||||
| 	bufLen := (width*2 + 1) * height | ||||
| 
 | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
| 
 | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
| @@ -72,8 +72,13 @@ func main() { | ||||
| 		board[column] = make([]bool, height) | ||||
| 	} | ||||
| 
 | ||||
| 	// drawing buffer length | ||||
| 	// *2 for extra spaces | ||||
| 	// +1 for newlines | ||||
| 	bufLen := (width*2 + 1) * height | ||||
| 
 | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
| 
 | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
| @@ -23,13 +23,14 @@ func main() { | ||||
| 		maxFrames = 1200 | ||||
| 		speed     = time.Second / 20 | ||||
| 
 | ||||
| 		initVx, initVy = 5, 2 | ||||
| 		// initial velocities | ||||
| 		ivx, ivy = 5, 2 | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		px, py   int        // ball position | ||||
| 		ppx, ppy int        // previous ball position | ||||
| 		vx, vy   = initVx, initVy // velocities | ||||
| 		vx, vy   = ivx, ivx // velocities | ||||
| 
 | ||||
| 		cell rune // current cell (for caching) | ||||
| 	) | ||||
| @@ -50,8 +51,13 @@ func main() { | ||||
| 		board[column] = make([]bool, height) | ||||
| 	} | ||||
| 
 | ||||
| 	// drawing buffer length | ||||
| 	// *2 for extra spaces | ||||
| 	// +1 for newlines | ||||
| 	bufLen := (width*2 + 1) * height | ||||
| 
 | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
| 
 | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
| @@ -62,10 +68,10 @@ func main() { | ||||
| 		py += vy | ||||
| 
 | ||||
| 		// when the ball hits a border reverse its direction | ||||
| 		if px <= 0 || px >= width-initVx { | ||||
| 		if px <= 0 || px >= width-ivx { | ||||
| 			vx *= -1 | ||||
| 		} | ||||
| 		if py <= 0 || py >= height-initVy { | ||||
| 		if py <= 0 || py >= height-ivx { | ||||
| 			vy *= -1 | ||||
| 		} | ||||
| 
 | ||||
| @@ -43,13 +43,14 @@ func main() { | ||||
| 		maxFrames = 1200 | ||||
| 		speed     = time.Second / 20 | ||||
| 
 | ||||
| 		initVx, initVy = 5, 2 | ||||
| 		// initial velocities | ||||
| 		ivx, ivy = 5, 2 | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		px, py   int        // ball position | ||||
| 		ppx, ppy int        // previous ball position | ||||
| 		vx, vy   = initVx, initVy // velocities | ||||
| 		vx, vy   = ivx, ivy // velocities | ||||
| 
 | ||||
| 		cell rune // current cell (for caching) | ||||
| 	) | ||||
| @@ -70,8 +71,13 @@ func main() { | ||||
| 		board[column] = make([]bool, height) | ||||
| 	} | ||||
| 
 | ||||
| 	// drawing buffer length | ||||
| 	// *2 for extra spaces | ||||
| 	// +1 for newlines | ||||
| 	bufLen := (width*2 + 1) * height | ||||
| 
 | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
| 
 | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
| @@ -82,10 +88,10 @@ func main() { | ||||
| 		py += vy | ||||
| 
 | ||||
| 		// when the ball hits a border reverse its direction | ||||
| 		if px <= 0 || px >= width-initVx { | ||||
| 		if px <= 0 || px >= width-ivx { | ||||
| 			vx *= -1 | ||||
| 		} | ||||
| 		if py <= 0 || py >= height-initVy { | ||||
| 		if py <= 0 || py >= height-ivy { | ||||
| 			vy *= -1 | ||||
| 		} | ||||
| 
 | ||||
| @@ -23,13 +23,14 @@ func main() { | ||||
| 		maxFrames = 1200 | ||||
| 		speed     = time.Second / 20 | ||||
| 
 | ||||
| 		initVx, initVy = 5, 2 | ||||
| 		// initial velocities | ||||
| 		ivx, ivy = 5, 2 | ||||
| 	) | ||||
| 
 | ||||
| 	var ( | ||||
| 		px, py   int        // ball position | ||||
| 		ppx, ppy int        // previous ball position | ||||
| 		vx, vy   = initVx, initVy // velocities | ||||
| 		vx, vy   = ivx, ivy // velocities | ||||
| 
 | ||||
| 		cell rune // current cell (for caching) | ||||
| 	) | ||||
| @@ -47,8 +48,13 @@ func main() { | ||||
| 	// create a single-dimensional board | ||||
| 	board := make([]bool, width*height) | ||||
| 
 | ||||
| 	// drawing buffer length | ||||
| 	// *2 for extra spaces | ||||
| 	// +1 for newlines | ||||
| 	bufLen := (width*2 + 1) * height | ||||
| 
 | ||||
| 	// create a drawing buffer | ||||
| 	buf := make([]rune, 0, width*height) | ||||
| 	buf := make([]rune, 0, bufLen) | ||||
| 
 | ||||
| 	// clear the screen once | ||||
| 	screen.Clear() | ||||
| @@ -59,15 +65,13 @@ func main() { | ||||
| 		py += vy | ||||
| 
 | ||||
| 		// when the ball hits a border reverse its direction | ||||
| 		if px <= 0 || px >= width-initVx { | ||||
| 		if px <= 0 || px >= width-ivx { | ||||
| 			vx *= -1 | ||||
| 		} | ||||
| 		if py <= 0 || py >= height-initVy { | ||||
| 		if py <= 0 || py >= height-ivy { | ||||
| 			vy *= -1 | ||||
| 		} | ||||
| 
 | ||||
| 		// check whether the ball goes beyond the borders | ||||
| 		if px < width && py < height { | ||||
| 		// calculate the new and the previous ball positions | ||||
| 		pos := py*width + px | ||||
| 		ppos := ppy*width + ppx | ||||
| @@ -77,7 +81,6 @@ func main() { | ||||
| 
 | ||||
| 		// save the previous positions | ||||
| 		ppx, ppy = px, py | ||||
| 		} | ||||
| 
 | ||||
| 		// rewind the buffer (allow appending from the beginning) | ||||
| 		buf = buf[:0] | ||||
		Reference in New Issue
	
	Block a user