From f67796ecf4ec5c9dbd57b41f8939f6557681a9dc Mon Sep 17 00:00:00 2001 From: Manish Kumar <73126278+ManishKumar219@users.noreply.github.com> Date: Wed, 19 Oct 2022 00:12:38 +0530 Subject: [PATCH 1/3] Create minmax.py --- backtracking/minmax.py | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 backtracking/minmax.py diff --git a/backtracking/minmax.py b/backtracking/minmax.py new file mode 100644 index 000000000000..6e310131e069 --- /dev/null +++ b/backtracking/minmax.py @@ -0,0 +1,70 @@ +""" +Minimax helps to achieve maximum score in a game by checking all possible moves +depth is current depth in game tree. + +nodeIndex is index of current node in scores[]. +if move is of maximizer return true else false +leaves of game tree is stored in scores[] +height is maximum height of Game tree +""" +from __future__ import annotations + +import math + + +def minimax( + depth: int, node_index: int, is_max: bool, scores: list[int], height: float +) -> int: + """ + >>> import math + >>> scores = [90, 23, 6, 33, 21, 65, 123, 34423] + >>> height = math.log(len(scores), 2) + >>> minimax(0, 0, True, scores, height) + 65 + >>> minimax(-1, 0, True, scores, height) + Traceback (most recent call last): + ... + ValueError: Depth cannot be less than 0 + >>> minimax(0, 0, True, [], 2) + Traceback (most recent call last): + ... + ValueError: Scores cannot be empty + >>> scores = [3, 5, 2, 9, 12, 5, 23, 23] + >>> height = math.log(len(scores), 2) + >>> minimax(0, 0, True, scores, height) + 12 + """ + + if depth < 0: + raise ValueError("Depth cannot be less than 0") + + if len(scores) == 0: + raise ValueError("Scores cannot be empty") + + if depth == height: + return scores[node_index] + + if is_max: + return max( + minimax(depth + 1, node_index * 2, False, scores, height), + minimax(depth + 1, node_index * 2 + 1, False, scores, height), + ) + + return min( + minimax(depth + 1, node_index * 2, True, scores, height), + minimax(depth + 1, node_index * 2 + 1, True, scores, height), + ) + + +def main() -> None: + scores = [90, 23, 6, 33, 21, 65, 123, 34423] + height = math.log(len(scores), 2) + print("Optimal value : ", end="") + print(minimax(0, 0, True, scores, height)) + + +if __name__ == "__main__": + import doctest + + doctest.testmod() + main() From d87809f747779aed0c7c03f6b613f9694431bcda Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 18 Oct 2022 21:15:28 +0200 Subject: [PATCH 2/3] Update minmax.py --- backtracking/minmax.py | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/backtracking/minmax.py b/backtracking/minmax.py index 6e310131e069..4c0121d9fb82 100644 --- a/backtracking/minmax.py +++ b/backtracking/minmax.py @@ -1,11 +1,6 @@ """ -Minimax helps to achieve maximum score in a game by checking all possible moves -depth is current depth in game tree. +Minimax helps to achieve maximum score in a game by checking all possible moves. -nodeIndex is index of current node in scores[]. -if move is of maximizer return true else false -leaves of game tree is stored in scores[] -height is maximum height of Game tree """ from __future__ import annotations @@ -16,7 +11,11 @@ def minimax( depth: int, node_index: int, is_max: bool, scores: list[int], height: float ) -> int: """ - >>> import math + depth is current depth in game tree. + node_index is index of current node in scores[]. + scores[] contains the leaves of game tree. + height is maximum height of game tree. + >>> scores = [90, 23, 6, 33, 21, 65, 123, 34423] >>> height = math.log(len(scores), 2) >>> minimax(0, 0, True, scores, height) @@ -38,19 +37,16 @@ def minimax( if depth < 0: raise ValueError("Depth cannot be less than 0") - if len(scores) == 0: + if not scores: raise ValueError("Scores cannot be empty") if depth == height: return scores[node_index] - if is_max: - return max( - minimax(depth + 1, node_index * 2, False, scores, height), - minimax(depth + 1, node_index * 2 + 1, False, scores, height), - ) - - return min( + return max( + minimax(depth + 1, node_index * 2, False, scores, height), + minimax(depth + 1, node_index * 2 + 1, False, scores, height), + ) if is_max else min( minimax(depth + 1, node_index * 2, True, scores, height), minimax(depth + 1, node_index * 2 + 1, True, scores, height), ) @@ -59,8 +55,7 @@ def minimax( def main() -> None: scores = [90, 23, 6, 33, 21, 65, 123, 34423] height = math.log(len(scores), 2) - print("Optimal value : ", end="") - print(minimax(0, 0, True, scores, height)) + print(f"Optimal value : {minimax(0, 0, True, scores, height)}") if __name__ == "__main__": From 1c582994763ceab0546798c9099e698f659e6858 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 18 Oct 2022 19:17:56 +0000 Subject: [PATCH 3/3] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- backtracking/minmax.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/backtracking/minmax.py b/backtracking/minmax.py index 4c0121d9fb82..9b87183cfdb7 100644 --- a/backtracking/minmax.py +++ b/backtracking/minmax.py @@ -43,12 +43,16 @@ def minimax( if depth == height: return scores[node_index] - return max( - minimax(depth + 1, node_index * 2, False, scores, height), - minimax(depth + 1, node_index * 2 + 1, False, scores, height), - ) if is_max else min( - minimax(depth + 1, node_index * 2, True, scores, height), - minimax(depth + 1, node_index * 2 + 1, True, scores, height), + return ( + max( + minimax(depth + 1, node_index * 2, False, scores, height), + minimax(depth + 1, node_index * 2 + 1, False, scores, height), + ) + if is_max + else min( + minimax(depth + 1, node_index * 2, True, scores, height), + minimax(depth + 1, node_index * 2 + 1, True, scores, height), + ) )