moves.ha (2902B)
1 use math; 2 3 fn invalid(x2: i64, y2: i64) bool = 4 if (x2 < 0 || y2 < 0 || x2 >= 8 || y2 >= 8) true 5 else false; 6 7 fn selftake(p: piece, b: board, x2: i64, y2: i64) bool = 8 match (getpiece(&b, x2, y2)) { 9 case let p2: *piece => return (p2.team == p.team); 10 case => return false; 11 }; 12 13 fn checkdiag(p: piece, b: board, x2: i64, y2: i64) bool = { 14 if (math::absi64(x2 - p.x) == math::absi64(y2 - p.y)) { 15 let xdir = if ((x2 - p.x) > 0) 1 else -1; 16 let ydir = if ((y2 - p.y) > 0) 1 else -1; 17 let y = p.y + ydir; 18 for (let x = p.x + xdir; x != x2; x += xdir) { 19 let p2 = getpiece(&b, x, y); 20 if (!(p2 is empty)) return false; 21 y += ydir; 22 }; 23 return true; 24 }; 25 26 return false; 27 }; 28 29 fn checkstraight(p: piece, b: board, x2: i64, y2: i64) bool = { 30 if (p.x == x2) { 31 let xdir = if ((x2 - p.x) > 0) 1 else -1; 32 for (let x = p.x; x != x2; x += xdir) { 33 let p2 = getpiece(&b, x, p.y); 34 if (!(p2 is empty)) return false; 35 }; 36 return true; 37 } else if (p.y == y2) { 38 let ydir = if ((y2 - p.y) > 0) 1 else -1; 39 for (let y = p.y; y != y2; y += ydir) { 40 let p2 = getpiece(&b, p.x, y); 41 if (!(p2 is empty)) return false; 42 }; 43 return true; 44 }; 45 46 return false; 47 }; 48 49 fn kingmove(p: piece, b: board, x2: i64, y2: i64) bool = { 50 if (invalid(x2, y2)) return false 51 else if (selftake(p, b, x2, y2)) return false 52 else if (math::absi64(x2 - p.x) > 1 || math::absi64(y2 - p.y) > 1) return false; 53 54 let p2 = getpiece(&b, x2, y2); 55 if (p2 is empty || (p2 as *piece).team != p.team) return true; 56 57 return false; 58 }; 59 60 fn queenmove(p: piece, b: board, x2: i64, y2: i64) bool = 61 if (invalid(x2, y2)) false 62 else if (selftake(p, b, x2, y2)) false 63 else if (checkdiag(p, b, x2, y2)) true 64 else if (checkstraight(p, b, x2, y2)) true 65 else false; 66 67 fn bishopmove(p: piece, b: board, x2: i64, y2: i64) bool = 68 if (invalid(x2, y2)) false 69 else if (selftake(p, b, x2, y2)) false 70 else if (checkdiag(p, b, x2, y2)) true 71 else false; 72 73 fn rookmove(p: piece, b: board, x2: i64, y2: i64) bool = 74 if (invalid(x2, y2)) false 75 else if (selftake(p, b, x2, y2)) false 76 else if (checkstraight(p, b, x2, y2)) true 77 else false; 78 79 fn knightmove(p: piece, b: board, x2: i64, y2: i64) bool = 80 if (invalid(x2, y2)) false 81 else if (selftake(p, b, x2, y2)) return false 82 else if (math::absi64(x2 - p.x) == 1 && math::absi64(y2 - p.y) == 2) true 83 else if (math::absi64(x2 - p.x) == 2 && math::absi64(y2 - p.y) == 1) true 84 else false; 85 86 fn pawnmove(p: piece, b: board, x2: i64, y2: i64) bool = { 87 if (invalid(x2, y2)) return false 88 else if (selftake(p, b, x2, y2)) return false 89 else if (p.moved && math::absi64(y2 - p.y) > 1) return false 90 else if (!p.moved && math::absi64(y2 - p.y) > 2) return false; 91 92 if (x2 == p.x + 1 || x2 == p.x - 1 || x2 == p.x) { 93 match (getpiece(&b, x2, y2)) { 94 case let p2: *piece => return (x2 != p.x && p2.team != p.team); 95 case !empty => return (x2 == p.x); 96 case => return false; 97 }; 98 }; 99 100 return false; 101 };