betterchess

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 };