Create an account


Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Fedora - Demonstrating Perl with Tic-Tac-Toe, Part 4

#1
Demonstrating Perl with Tic-Tac-Toe, Part 4

This is the final article to the series demonstrating Perl with Tic-Tac-Toe. This article provides a module that can compute better game moves than the previously presented modules. For fun, the modules chip1.pm through chip3.pm can be incrementally moved out of the hal subdirectory in reverse order. With each chip that is removed, the game will become easier to play. The game must be restarted each time a chip is removed.

An example Perl program


Copy and paste the below code into a plain text file and use the same one-liner that was provided in the the first article of this series to strip the leading numbers. Name the version without the line numbers chip3.pm and move it into the hal subdirectory. Use the version of the game that was provided in the second article so that the below chip will automatically load when placed in the hal subdirectory. Be sure to also include both chip1.pm and chip2.pm from the second and third articles, respectively, in the hal subdirectory.

00 # artificial intelligence chip
01 02 package chip3;
03 require chip2;
04 require chip1;
05 06 use strict;
07 use warnings;
08 09 sub moverama {
10 my $game = shift;
11 my @nums = $game =~ /[1-9]/g;
12 my $rama = qr/[1973]/;
13 my %best;
14 15 for (@nums) {
16 my $ra = $_;
17 next unless $ra =~ $rama;
18 $best{$ra} = 0;
19 for (@nums) {
20 my $ma = $_;
21 next unless $ma =~ $rama;
22 if (($ra-$ma)*(10-$ra-$ma)) {
23 $best{$ra} += 1;
24 }
25 }
26 }
27 28 @nums = sort { $best{$b} <=> $best{$a} } keys %best;
29 30 return $nums[0];
31 }
32 33 sub hal_move {
34 my $game = shift;
35 my $mark = shift;
36 my @mark = @{ shift; };
37 my $move;
38 39 $move = chip2::win_move $game, $mark, \@mark;
40 41 if (not defined $move) {
42 $mark = ($mark eq $mark[0]) ? $mark[1] : $mark[0];
43 $move = chip2::win_move $game, $mark, \@mark;
44 }
45 46 if (not defined $move) {
47 $move = moverama $game;
48 }
49 50 if (not defined $move) {
51 $move = chip1::hal_move $game;
52 }
53 54 return $move;
55 }
56 57 sub complain {
58 print 'Just what do you think you\'re doing, ',
59 ((getpwnam($ENV{'USER'}))[6]||$ENV{'USER'}) =~ s! .*!!r, "?\n";
60 }
61 62 sub import {
63 no strict;
64 no warnings;
65 66 my $p = __PACKAGE__;
67 my $c = caller;
68 69 *{ $c . '::hal_move' } = \&{ $p . '::hal_move' };
70 *{ $c . '::complain' } = \&{ $p . '::complain' };
71 72 if (&::MARKS->[0] ne &::HAL9K) {
73 @{ &::MARKS } = reverse @{ &::MARKS };
74 }
75 }
76 77 1;

How it works


Rather than making a random move or making a move based on probability, this final module to the Perl Tic-Tac-Toe game uses a more deterministic algorithm to calculate the best move.

The big takeaway from this Perl module is that it is yet another example of how references can be misused or abused, and as a consequence lead to unexpected program behavior. With the addition of this chip, the computer learns to cheat. Can you figure out how it is cheating? Hints:

  1. Constants are implemented as subroutines.
  2. References allow data to be modified out of scope.

Final notes


Line 12 demonstrates that a regular expression can be pre-compiled and stored in a scalar for later use. This is useful as performance optimization when you intend to re-use the same regular expression many times over.

Line 59 demonstrates that some system library calls are available directly in Perl’s built-in core functionality. Using the built-in functions alleviates some overhead that would otherwise be required to launch an external program and setup the I/O channels to communicate with it.

Lines 72 and 73 demonstrate the use of &:: as a shorthand for &main::.

The full source code for this Perl game can be cloned from the git repository available here: https://pagure.io/tic-tac-toe.git



https://www.sickgaming.net/blog/2020/07/...oe-part-4/
Reply



Possibly Related Threads…
Thread Author Replies Views Last Post
  Fedora - Web of Trust, Part 2: Tutorial xSicKxBot 0 1,691 10-19-2020, 05:41 PM
Last Post: xSicKxBot
  Fedora - Web of Trust, Part 1: Concept xSicKxBot 0 1,589 10-14-2020, 02:14 PM
Last Post: xSicKxBot
  Fedora - LaTeX typesetting, Part 3: formatting xSicKxBot 0 1,581 07-25-2020, 05:37 AM
Last Post: xSicKxBot
  Fedora - Demonstrating Perl with Tic-Tac-Toe, Part 3 xSicKxBot 0 1,640 07-04-2020, 05:49 AM
Last Post: xSicKxBot
  Fedora - LaTeX typesetting part 2 (tables) xSicKxBot 0 1,672 06-30-2020, 04:22 AM
Last Post: xSicKxBot
  Fedora - LaTeX Typesetting – Part 1 (Lists) xSicKxBot 0 1,713 06-16-2020, 03:10 AM
Last Post: xSicKxBot
  Fedora - Using Fedora to implement REST API in JavaScript: part 2 xSicKxBot 0 1,560 06-05-2020, 02:00 PM
Last Post: xSicKxBot
  Fedora - Using Fedora to implement REST API in JavaScript: part 2 xSicKxBot 0 1,517 05-18-2020, 09:23 PM
Last Post: xSicKxBot
  Fedora - Fedora Origins – Part 01 xSicKxBot 0 1,490 04-15-2020, 09:46 PM
Last Post: xSicKxBot
  Fedora - Demonstrating PERL with Tic-Tac-Toe, Part 2 xSicKxBot 0 1,610 03-03-2020, 05:45 AM
Last Post: xSicKxBot

Forum Jump:


Users browsing this thread:
1 Guest(s)

Forum software by © MyBB Theme © iAndrew 2016