Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

ASCII Battleship Program

by perlStuck (Sexton)
on Feb 04, 2012 at 01:09 UTC ( [id://951741]=CUFP: print w/replies, xml ) Need Help??

This is a program I wrote some number of months back for an ASCII based battleship program, when I had much less of a concept of the optimization of code. It is certainly not the most effective use of the code. That is, there is quite a lot of repetition, and I have some rather useless prototyping in there that really doesn't mean a lot. As well, I never really got around to building the AI subs for it. Please note that also, the program tends to freeze in salvo mode, due to the fact that it has to figure out a way to "fire" in a manner that wouldn't make it so that locations would be hit more than once. Anyway, just thought I'd put it up here. If you want to change the code around to optimize it or make it function better, that would be great, and I'd love to see it. Or, if you just want to download it and feel completely old-school as you're playing, feel free to do that as well! Enjoy! Happy perling!

#!\usr\local\bin\perl use v5.10.1; use strict; &startup(); #********************************************************************* +********* #*******************************STARTUP FUNCTION********************** +********* #********************************************************************* +********* sub main::startup () { local $main::startup::name = ""; print "\n\nPlease enter your name: "; chomp($main::startup::name = <STDIN>); &main::call; } #********************************************************************* +********** #******************************MAIN CALL FUNCTION********************* +********** #********************************************************************* +********** sub main::call () { srand; local @main::com_ships::com_all_ships = (); local @main::com_ships::com_carrier = (); local @main::com_ships::com_battleship = (); local @main::com_ships::com_destroyer = (); local @main::com_ships::com_patrol = (); local @main::user_ships::user_all_ships = (); local @main::user_ships::user_carrier = (); local @main::user_ships::user_battleship = (); local @main::user_ships::user_destroyer = (); local @main::user_ships::user_submarine = (); local @main::user_ships::user_patrol = (); local @main::com_ships::com_board = ( [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], ); local @main::user_ships::user_board = ( [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], ); local @main::letters::letters = ("A" .. "J"); local $main::game_play::whos_first = ''; local $main::game_play::mode = ''; local @main::game_play::com_shots_check; local @main::game_play::user_shots_check; local $main::com_ships::hits = ''; local $main::user_ships::hits = ''; &generate_ship_pos::start(); &get_user_ship_pos::start(); &game_play::start(); } #********************************************************************* +********** #***************************SECONDARY CALL FUNCTIONS****************** +********** #********************************************************************* +********** sub generate_ship_pos::start () { &generate_ship_pos::carrier(); &generate_ship_pos::battleship(); &generate_ship_pos::destroyer(); &generate_ship_pos::submarine(); &generate_ship_pos::patrol(); &generate_ship_pos::correctional(@main::com_ships::com_all_ships); } sub get_user_ship_pos::start () { &get_user_ship_pos::carrier(); &get_user_ship_pos::battleship(); &get_user_ship_pos::destroyer(); &get_user_ship_pos::submarine(); &get_user_ship_pos::patrol(); } sub game_play::start () { $main::game_play::whos_first = &game_play::decide(); $main::game_play::mode = &game_play::mode(); &game_play::tree_branches($main::game_play::whos_first, $main::game_p +lay::mode); } #********************************************************************* +********** #*********************COMPUTER SHIP GENERATION FUNCTIONS************** +********** #********************************************************************* +********** sub generate_ship_pos::carrier () { while (@main::com_ships::com_carrier != 5) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_carrier = ("$x" . "$y", "$x" . "$y"+1, +"$x" . "$y"+2, "$x" . "$y"+3, "$x" . "$y"+4); } if ($y > 2 and $y <= 6) { @main::com_ships::com_carrier = ("$x" . "$y"-2, "$x" . "$y"-1 +, "$x" . "$y", "$x" . "$y"+1, "$x" . "$y"+2); } if ($y > 6) { @main::com_ships::com_carrier = ("$x" . "$y"-4, "$x" . "$y"-3 +, "$x" . "$y"-2, "$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_carrier = ("$x" . "$y", "$x"+1 . "$y", +"$x"+2 . "$y", "$x"+3 . "$y", "$x"+4 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_carrier = ("$x"-2 . "$y", "$x"-1 . "$y" +, "$x" . "$y", "$x"+1 . "$y", "$x"+2 . "$y"); } if ($x > 6) { @main::com_ships::com_carrier = ("$x"-4 . "$y", "$x"-3 . "$y" +, "$x"-2 . "$y", "$x"-1 . "$y", "$x" . "$y"); } } push @main::com_ships::com_all_ships, @main::com_ships::com_carrier +; } } sub generate_ship_pos::battleship () { while (@main::com_ships::com_battleship != 4) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_battleship = ("$x" . "$y", "$x" . "$y"+ +1, "$x" . "$y"+2, "$x" . "$y"+3); } if ($y > 2 and $y <= 6) { @main::com_ships::com_battleship = ("$x" . "$y"-2, "$x" . "$y +"-1, "$x" . "$y", "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_battleship = ("$x" . "$y"-3, "$x" . "$y +"-2, "$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_battleship = ("$x" . "$y", "$x"+1 . "$y +", "$x"+2 . "$y", "$x"+3 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_battleship = ("$x"-2 . "$y", "$x"-1 . " +$y", "$x" . "$y", "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_battleship = ("$x"-3 . "$y", "$x"-2 . " +$y", "$x"-1 . "$y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_battleship) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_battleship = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_battle +ship; } } sub generate_ship_pos::destroyer () { while (@main::com_ships::com_destroyer != 3) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_destroyer = ("$x" . "$y", "$x" . "$y"+1 +, "$x" . "$y"+2); } if ($y > 2 and $y <= 6) { @main::com_ships::com_destroyer = ("$x" . "$y"-1, "$x" . "$y" +, "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_destroyer = ("$x" . "$y"-2, "$x" . "$y" +-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_destroyer = ("$x" . "$y", "$x"+1 . "$y" +, "$x"+2 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_destroyer = ("$x"-1 . "$y", "$x" . "$y" +, "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_destroyer = ("$x"-2 . "$y", "$x"-1 . "$ +y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_destroyer) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_destroyer = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_destro +yer; } } sub generate_ship_pos::submarine () { while (@main::com_ships::com_submarine != 3) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_submarine = ("$x" . "$y", "$x" . "$y"+1 +, "$x" . "$y"+2); } if ($y > 2 and $y <= 6) { @main::com_ships::com_submarine = ("$x" . "$y"-1, "$x" . "$y" +, "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_submarine = ("$x" . "$y"-2, "$x" . "$y" +-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_submarine = ("$x" . "$y", "$x"+1 . "$y" +, "$x"+2 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_submarine = ("$x"-1 . "$y", "$x" . "$y" +, "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_submarine = ("$x"-2 . "$y", "$x"-1 . "$ +y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_submarine) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_submarine = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_submar +ine; } } sub generate_ship_pos::patrol () { while (@main::com_ships::com_patrol != 2) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_patrol = ("$x" . "$y", "$x" . "$y"+1); } if ($y > 2 and $y <= 6) { @main::com_ships::com_patrol = ( "$x" . "$y", "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_patrol = ("$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_patrol = ("$x" . "$y", "$x"+1 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_patrol = ("$x" . "$y", "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_patrol = ("$x"-1 . "$y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_patrol) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_patrol = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_patrol +; } } sub generate_ship_pos::correctional() { foreach my $el (@main::com_ships::com_all_ships) { if (length $el == 1) { $el = '0' . "$el"; } } } #********************************************************************* +********** #************************USER SHIP GENERATION FUNCTIONS*************** +********** #********************************************************************* +********** sub get_user_ship_pos::carrier () { my @user_carrier_check_let = (); my @user_carrier_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your carrier positions (e.g. A4): "; chomp($input = <STDIN>); @main::user_ships::user_carrier = split(" ", $input); unless ($input =~ /^([A-J]\d0?\s){4}[A-J]\d0?$/i) { print "You have entered invalid input. Please try again.\n\n"; $input = ''; @main::user_ships::user_carrier = (); $decide = 0; } unless ($decide) { &get_user_ship_pos::carrier(); return 0; } foreach my $el (@main::user_ships::user_carrier) { my ($let, $one, $two) = split('', $el); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_carrier = (); &get_user_ship_pos::carrier(); } } push @user_carrier_check_let, $let; push @user_carrier_check_num, $num; } @user_carrier_check_let = sort {$a <=> $b} @user_carrier_check_let; @user_carrier_check_num = sort {$a <=> $b} @user_carrier_check_num; my $string_alet = $user_carrier_check_let[0] . $user_carrier_check_le +t[1] . $user_carrier_check_let[2] . $user_carrier_check_let[3] . $use +r_carrier_check_let[4]; my $string_anum = $user_carrier_check_num[0] . $user_carrier_check_nu +m[1] . $user_carrier_check_num[2] . $user_carrier_check_num[3] . $use +r_carrier_check_num[4]; if ('0123456789' =~ /$string_anum/ and '0123456789' =~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_carrier = (); &get_user_ship_pos::carrier(); return 0; } if ('0123456789' !~ /$string_anum/ and '0123456789' !~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_carrier = (); &get_user_ship_pos::carrier(); return 0; } foreach my $el (@main::user_ships::user_carrier) { my ($let, $num) = split('', $el); $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_carri +er; } sub get_user_ship_pos::battleship () { my @user_battleship_check_let = (); my @user_battleship_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your battleship positions: "; chomp($input = <STDIN>); @main::user_ships::user_battleship = split(" ", $input); unless ($input =~ /^([A-J]\d0?\s){3}[A-J]\d0?$/i) { print "You have entered invalid input. Please try again.\n\n"; $input = ''; @main::user_ships::user_battleship = (); $decide = 0; } unless ($decide) { &get_user_ship_pos::battleship(); return 0; } foreach my $el (@main::user_ships::user_battleship) { my ($let, $one, $two) = split('', $el); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_battleship = (); &get_user_ship_pos::battleship(); } } push @user_battleship_check_let, $let; push @user_battleship_check_num, $num; } foreach my $el (@main::user_ships::user_all_ships) { foreach my $lee (@main::user_ships::user_battleship) { if ($lee =~ /$el/i and $el =~/$lee/i) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_battleship = (); &get_user_ship_pos::battleship(); return 0; } } } @user_battleship_check_let = sort {$a <=> $b} @user_battleship_check_ +let; @user_battleship_check_num = sort {$a <=> $b} @user_battleship_check_ +num; my $string_alet = $user_battleship_check_let[0] . $user_battleship_ch +eck_let[1] . $user_battleship_check_let[2] . $user_battleship_check_l +et[3]; my $string_anum = $user_battleship_check_num[0] . $user_battleship_ch +eck_num[1] . $user_battleship_check_num[2] . $user_battleship_check_n +um[3]; if ('0123456789' =~ /$string_anum/ and '0123456789' =~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_battleship = (); &get_user_ship_pos::battleship(); return 0; } if ('0123456789' !~ /$string_anum/ and '0123456789' !~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_battleship = (); &get_user_ship_pos::battleship(); return 0; } foreach my $el (@main::user_ships::user_battleship) { my ($let, $num) = split('', $el); $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_battl +eship; } sub get_user_ship_pos::destroyer () { my @user_destroyer_check_let = (); my @user_destroyer_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your destroyer positions (e.g. A4): "; chomp($input = <STDIN>); @main::user_ships::user_destroyer = split(" ", $input); unless ($input =~ /^([A-J]\d0?\s?){2}[A-J]\d0?$/i) { print "You have entered invalid input. Please try again.\n\n"; $input = ''; @main::user_ships::user_destroyer = (); $decide = 0; } unless ($decide) { &get_user_ship_pos::destroyer(); return 0; } foreach my $el (@main::user_ships::user_destroyer) { my ($let, $one, $two) = split('', $el); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_destroyer = (); &get_user_ship_pos::destroyer(); } } push @user_destroyer_check_let, $let; push @user_destroyer_check_num, $num; } foreach my $el (@main::user_ships::user_all_ships) { foreach my $lee (@main::user_ships::user_destroyer) { if ($lee =~ /$el/i and $el =~/$lee/i) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_destroyer = (); &get_user_ship_pos::destroyer(); return 0; } } } @user_destroyer_check_let = sort {$a <=> $b} @user_destroyer_check_le +t; @user_destroyer_check_num = sort {$a <=> $b} @user_destroyer_check_nu +m; my $string_alet = $user_destroyer_check_let[0] . $user_destroyer_chec +k_let[1] . $user_destroyer_check_let[2]; my $string_anum = $user_destroyer_check_num[0] . $user_destroyer_chec +k_num[1] . $user_destroyer_check_num[2]; if ('0123456789' =~ /$string_anum/ and '0123456789' =~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_destroyer = (); &get_user_ship_pos::destroyer(); return 0; } if ('0123456789' !~ /$string_anum/ and '0123456789' !~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_destroyer = (); &get_user_ship_pos::destroyer(); return 0; } foreach my $el (@main::user_ships::user_destroyer) { my ($let, $num) = split('', $el); $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_destr +oyer; } sub get_user_ship_pos::submarine () { my @user_submarine_check_let = (); my @user_submarine_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your submarine positions (e.g. A4): "; chomp($input = <STDIN>); @main::user_ships::user_submarine = split(" ", $input); unless ($input =~ /^([A-J]\d0?\s?){2}[A-J]\d0?$/i) { print "You have entered invalid input. Please try again.\n\n"; $input = ''; @main::user_ships::user_submarine = (); $decide = 0; } unless ($decide) { &get_user_ship_pos::submarine(); return 0; } foreach my $el (@main::user_ships::user_submarine) { my ($let, $one, $two) = split('', $el); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_submarine = (); &get_user_ship_pos::submarine(); } } push @user_submarine_check_let, $let; push @user_submarine_check_num, $num; } foreach my $el (@main::user_ships::user_all_ships) { foreach my $lee (@main::user_ships::user_submarine) { if ($lee =~ /$el/i and $el =~/$lee/i) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_submarine = (); &get_user_ship_pos::submarine(); return 0; } } } @user_submarine_check_let = sort {$a <=> $b} @user_submarine_check_le +t; @user_submarine_check_num = sort {$a <=> $b} @user_submarine_check_nu +m; my $string_alet = $user_submarine_check_let[0] . $user_submarine_chec +k_let[1] . $user_submarine_check_let[2]; my $string_anum = $user_submarine_check_num[0] . $user_submarine_chec +k_num[1] . $user_submarine_check_num[2]; if ('0123456789' =~ /$string_anum/ and '0123456789' =~ /$string_alet/ +) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_submarine = (); &get_user_ship_pos::submarine(); return 0; } if ('0123456789' !~ /$string_anum/ and '0123456789' !~ /$string_alet/ +) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_submarine = (); &get_user_ship_pos::submarine(); return 0; } foreach my $el (@main::user_ships::user_submarine) { my ($let, $num) = split('', $el); $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_subma +rine; } sub get_user_ship_pos::patrol () { my @user_patrol_check_let = (); my @user_patrol_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your patrol positions: "; chomp($input = <STDIN>); @main::user_ships::user_patrol = split(" ", $input); unless ($input =~ /^[A-J]\d0?\s[A-J]\d0?$/i) { print "You have entered invalid input. Please try again.\n\n"; $input = ''; @main::user_ships::user_patrol = (); $decide = 0; } unless ($decide) { &get_user_ship_pos::patrol(); return 0; } foreach my $el (@main::user_ships::user_patrol) { my ($let, $one, $two) = split('', $el); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_patrol = (); &get_user_ship_pos::patrol(); } } push @user_patrol_check_let, $let; push @user_patrol_check_num, $num; } foreach my $el (@main::user_ships::user_all_ships) { foreach my $lee (@main::user_ships::user_patrol) { if ($lee =~ /$el/i and $el =~/$lee/i) { print "Your input is invalid. Please try again.\n\n"; @main::user_ships::user_patrol = (); &get_user_ship_pos::patrol(); return 0; } } } @user_patrol_check_let = sort {$a <=> $b} @user_patrol_check_let; @user_patrol_check_num = sort {$a <=> $b} @user_patrol_check_num; my $string_alet = $user_patrol_check_let[0] . $user_patrol_check_let[ +1]; my $string_anum = $user_patrol_check_num[0] . $user_patrol_check_num[ +1]; if ('0123456789' =~ /$string_anum/ and '0123456789' =~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_patrol = (); &get_user_ship_pos::patrol(); return 0; } if ('0123456789' !~ /$string_anum/ and '0123456789' !~ /$string_alet/ +) { print "Your input is invalid. Please try aaaaagain.\n\n"; @main::user_ships::user_patrol = (); &get_user_ship_pos::patrol(); return 0; } foreach my $el (@main::user_ships::user_patrol) { my ($let, $num) = split('', $el); $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_patro +l; } #********************************************************************* +********** #*******************************GAME-PLAY FUNCTIONS******************* +********** #********************************************************************* +********** sub game_play::decide () { my $decide = ''; while (!$decide) { print "\n1. You ($main::startup::name)"; print "\n2. Computer"; print "\n3. Random"; print "\n\nPlease enter digit to decide who goes first: "; chomp($decide = <STDIN>); if ($decide == 1 or $decide == 2) { return $decide; } elsif ($decide = 3) { return int(rand(1000)); } else { print "Your slection is not recognized. Please try again.\n"; $decide = ''; } } } sub game_play::mode () { my $mode = ''; while (!$mode) { print "\n1. Regular"; print "\n2. Three-shot salvo"; print "\n\nPlease enter mode selection: "; chomp($mode = <STDIN>); if ($mode == 1 or $mode == 2) { return $mode; } else { print "Your slection is not recognized. Please try again.\n"; $mode = ''; } } } sub game_play::tree_branches () { my @deciders = @_; if ($deciders[0]/2 == int($deciders[0]/2)){ &game_play::com_start($deciders[1]); } else { &game_play::user_start($deciders[1]); } } sub game_play::com_start () { my ($decider) = @_; print "COMPUTER STARTS . . . .\n\n"; sleep 1; if ($decider == 2) { &game_play::com_start::salvo_mode(); } elsif ($decider == 1) { &game_play::com_start::reg_mode(); } } sub game_play::user_start () { my ($decider) = @_; print "$main::startup::name STARTS . . . .\n\n"; if ($decider == 2) { &game_play::user_start::salvo_mode(); } else { &game_play::user_start::reg_mode(); } } sub game_play::com_start::salvo_mode() { while (!&game_play::dead_yet()) { &game_play::salvo_mode::com_salvo(); &game_play::dead_yet(); print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::salvo_mode::user_salvo(); &game_play::dead_yet(); } } sub game_play::com_start::reg_mode() { while (!&game_play::dead_yet()) { &game_play::reg_mode::com_shot(); &game_play::dead_yet(); print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::reg_mode::user_shot(); &game_play::dead_yet(); } } sub game_play::user_start::salvo_mode() { while (!&game_play::dead_yet()) { print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::salvo_mode::user_salvo(); &game_play::dead_yet(); &game_play::salvo_mode::com_salvo(); &game_play::dead_yet(); } } sub game_play::user_start::reg_mode() { while (!&game_play::dead_yet()) { print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::reg_mode::user_shot(); &game_play::dead_yet(); &game_play::reg_mode::com_shot(); &game_play::dead_yet(); } } sub game_play::salvo_mode::com_salvo () { my $x1 = int(rand(10)); my $y1 = int(rand(10)); my $x2 = int(rand(10)); my $y2 = int(rand(10)); my $x3 = int(rand(10)); my $y3 = int(rand(10)); my @temp_checker = ("$x1" . "$y1", "$x2" . "$y2", "$x3" . "$y3"); if (($main::user_ships::user_board[$x1][$y1] eq 'X') or ($main::user_ +ships::user_board[$x1][$y1] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } if (($main::user_ships::user_board[$x3][$y3] eq 'X') or ($main::user_ +ships::user_board[$x3][$y3] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } if (($main::user_ships::user_board[$x2][$y2] eq 'X') or ($main::user_ +ships::user_board[$x2][$y2] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } push @main::game_play::com_shots_check, @temp_checker; if ($main::user_ships::user_board[$x1][$y1] eq '#') { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x1][$y1] = 'X'; } elsif ($main::user_ships::user_board[$x1][$y1] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x1][$y1] = 'O'; } if ($main::user_ships::user_board[$x2][$y2] eq '#') { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x2][$y2] = 'X'; } elsif ($main::user_ships::user_board[$x2][$y2] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x2][$y2] = 'O'; } if ($main::user_ships::user_board[$x3][$y3] eq '#') { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x3][$y3] = 'X'; } elsif ($main::user_ships::user_board[$x3][$y3] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x3][$y3] = 'O'; } } sub game_play::salvo_mode::user_salvo () { my $input = ''; print "\n Please enter your three salvo shots: "; chomp($input = <STDIN>); my @user_shots = split(" ", $input); if ($input !~ /^[A-J]\d0?\s[A-J]\d0?\s[A-J]\d0?$/i) { print "You've entered invalid input. Please try again.\n"; &game_play::salvo_mode::user_salvo(); return 0; } if ($user_shots[0] eq ($user_shots[1] or $user_shots[2]) or $user_sho +ts[1] eq $user_shots[2]) { print "You have entered a co-ordinate twice. Please try again.\n"; &game_play::salvo_mode::user_salvo(); return 0; } foreach my $el (@user_shots) { my ($let, $one, $two) = split('', $el); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; @user_shots = (); &game_play::salvo_mode::user_salvo(); return; } } foreach my $lee (@main::game_play::user_shots_check) { if ($el eq $lee) { print "You have entered invalid input. Please try again.\n"; &game_play::salvo_mode::user_salvo(); return; } } foreach my $lee (@main::com_ships::com_all_ships) { if ($el eq $lee) { print "Computer ship hit!\n"; $main::com_ships::com_board[$let][$num] = 'X'; $main::com_ships::hits++; last; } elsif ($el ne $lee) { $main::com_ships::com_board[$let][$num] = 'O'; } } } push @main::game_play::user_shots_check, @user_shots; } sub game_play::reg_mode::com_shot () { my $x1 = int(rand(10)); my $y1 = int(rand(10)); my $temp_checker = ("$x1" . "$y1"); if (($main::user_ships::user_board[$x1][$y1] eq 'X') or ($main::user_ +ships::user_board[$x1][$y1] eq 'O')) { &game_play::reg_mode::com_shot; return; } push @main::game_play::com_shots_check, $temp_checker; if ($main::user_ships::user_board[$x1][$y1] eq '#') { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x1][$y1] = 'X'; } elsif ($main::user_ships::user_board[$x1][$y1] eq 'X') { &game_play::reg_mode::com_shot; return; } else { $main::user_ships::user_board[$x1][$y1] = 'O'; } } sub game_play::reg_mode::user_shot () { my $input = ''; print "\n Please enter your target: "; chomp($input = <STDIN>); if ($input !~ /^[A-J]\d0?$/i) { print "You've entered invalid input. Please try again.\n"; &game_play::reg_mode::user_shot(); return 0; } my ($let, $one, $two) = split('', $input); given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $input = "$let" . "$num"; given ($num) { when ($num > 9) { print "Your input is invalid. Please try again.\n\n"; $input = ''; &game_play::reg_mode::user_shot(); return; } } foreach my $lee (@main::game_play::user_shots_check) { if ($input eq $lee) { print "You have entered invalid input. Please try again.\n"; &game_play::reg_mode::user_shot(); return; } } foreach my $lee (@main::com_ships::com_all_ships) { if ($input eq $lee) { print "Computer ship hit!\n"; $main::com_ships::com_board[$let][$num] = 'X'; $main::com_ships::hits++; last; } elsif ($input ne $lee) { $main::com_ships::com_board[$let][$num] = 'O'; } } push @main::game_play::user_shots_check, $input; } sub game_play::dead_yet () { if ($main::com_ships::hits eq '17') { &game_play::end_game(2); } if ($main::user_ships::hits eq '17') { &game_play::end_game(1); } } sub game_play::end_game () { my @winner = @_; if ($winner[0] == 2) { print "Congratulations! You won, $main::startup::name!\n\n"; exit; } else { print "Computer won. Better luck next time!\n"; exit; } } sub game_play::THE_END () { print "\n"; }

Replies are listed 'Best First'.
Code tuning (was Re: ASCII Battleship Program)
by roboticus (Chancellor) on Feb 04, 2012 at 05:36 UTC

    perlStuck:

    Very fun! For an early effort, it's pretty decent.

    Anyway, I'm stuck on a conference call as the $day_job is doing some software installs and may need to ask questions. So to amuse myself, I played the game, and then started tuning up the code.

    The first thing I noticed was this bit:

    given ($let) { when (/A/i) { $let = 0; } when (/B/i) { $let = 1; } when (/C/i) { $let = 2; } when (/D/i) { $let = 3; } when (/E/i) { $let = 4; } when (/F/i) { $let = 5; } when (/G/i) { $let = 6; } when (/H/i) { $let = 7; } when (/I/i) { $let = 8; } when (/J/i) { $let = 9; } }

    which I replaced with a subroutine:

    sub letter_to_coord { # Converts A .. J into 0 .. 9, assuming valid data entered. my $letter = uc(shift); my $num = ord($letter) - ord('A'); return $num if $num < 10 and $num >= 0; die "invalid input!"; }

    Since that was repeated six more times, it reduced the line count somewhat. I also noticed the board printing logic was used multiple times, so I wrote a couple subroutines:

    sub print_both_boards { print "USER BOARD:"; print_board(\@main::user_ships::user_board); print "COMPUTER BOARD:"; print_board(\@main::com_ships::com_board); } sub print_board { my $ar = shift; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; for (my $i=0; $i<@$ar; ++$i) { print "$main::letters::letters[$i]|"; my @t = map { $_ eq '0' ? '-' : $_ } @{$$ar[$i]}; print " @t\n"; } }

    Between those two changes, I cut out roughly 300 lines. I'll put the rest in readmore tags, so you don't have to suffer through all of it.

    There's a good bit more refactoring that could be done. Perhaps if the call cools down some, I'll revisit it.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

Re: ASCII Battleship Program
by davido (Cardinal) on Feb 04, 2012 at 07:28 UTC

    Bug report: When you try to place an entity on the board that has a width of less than five (the largest piece), the smaller piece shows up at an offset from where you actually try to place it.

    Example: Place a sub (three chars wide) at A7r. You can't. You must place it at A5r, in which case it appears at A6r, extends right three places, and leaves a blank slot in A10.

    It also seems (in the one game I played) that the computer placed two pieces overlapping. I could be wrong on that though.


    Dave

      Yeah, I think I found a partial solution at least. It would appear that two of the conditionals that would allow the return of a properly placed ship was faulty. In 'sub place_ship' there's a line that reads:

      return 0 if $x<0 or $y<0 or $x>9 or $y>9;

      Changing it to:

      return 0 if $x<0 or $y<0 or $x>10 or $y>10;
      That seems to work.
Re: ASCII Battleship Program
by CountZero (Bishop) on Feb 05, 2012 at 07:26 UTC
    A few comments:
    • All your subroutine definitions use the "no parameters" prototyping by virtue of adding "()" in their definitions. Indeed none of your subroutines take any parameters, so that is not wrong, but then you call al your subroutines by prepending "&" to their names which has the effect of ignoring any prototypes. It is far better to delete all the prototyping as it probably does not do what you think it does and also delete all the "&" in the sub-calls which serve no purpose here.
    • You have a peculiar way of naming your variables and subroutines. While not "wrong" as such, it is not the perlish way. I wonder what was your native computer language before you started programming in Perl. Anyhow, the use of "::" in variable names and subroutines is reserved for using packages ("namespaces", if you wish), but you do not use packages here and frankly for a program of this size that does not use any modules, it is overkill to use namespaces. Everything can safely live in the main package (which is the default package).
    • Your use of local is ... strange. Did you do it so your program runs under use strict;? Again, probably you have a wrong concept of what local does. If you want to declare global (in the sense of can-be-seen-and-accessed-everywhere) then you can safely use lexical "my" variables, placed outside of any subroutine or block.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      I do realize that in the context in which I have used it, protoyping is quite useless. This was at a time when I was rather unsure what prototyping really even was. I simply saw others doing it, and actually thought until recently that it was simply part of the manner in which one defined subroutines. As for the naming of the variables and subroutines, what I was originally planning to do with this was put all the code into one, large program that would allow me to select between other games I played, word processer, possibly an HTML Parser (probably some kind of open-source text-browser already out there) etc. etc. In fact, I was actually intending to make a whole OS-like 'shell' program, for the heck of it. Such aspirations were, naturally, soon abandoned, as such a program was hopelessly out of reach for me. I felt that the naming conventions I used would permit me a broader area of flexibility with which to write other mini-programs in the 'OS'. With local, all I was attempting to do was make it so that subroutines called by other subroutines had access to the same variables that called them. This was before I was particularly well aware of the practice of accepting arguments by use of the variable @_. I felt that such use of local suited my purposes fine, as it would keep all of the variables well within the bound of the battleship program, but would not allow them to seep out into the broader program. My native language is Perl. However, being self-taught, I've developed a style of programming that is probably not only not the greatest, but also simply rather strange looking. But I generally manage to get stuff done, so I'm generally pretty happy with how I code. I do rather fear for whoever's going to have to maintain my code, though . . . .

        That stranger who is going to maintain your code is ... you - about a month from now.

        True laziness is hard work
Re: ASCII Battleship Program
by roboticus (Chancellor) on Feb 14, 2012 at 18:43 UTC

    Hello, all--

    I had another software install over the weekend, and spent my slack time twiddling around with the Battleship game again. I've addressed a couple of the issues, and undoubtedly added some new issues. The current version displays the computer's ships for debugging, but I haven't tweaked the code to let me turn off the computer ship display yet.

    I'm posting the updated version just in case I get pulled away again and never see it again. Hopefully someone else will tweak it a little too.

      I got this running on V. 5.006 from the command line

      It sinks a ship by hitting it once

      There are 5 ships, carrier, battleship, destroyer, submarine, patrol.

      When the computer has hit all the ships and choosen all the spaces it errors, out of memory!

      It assigns a pound sign # to every ship but I changed that to assign a different sign for each ship # * % ^ ~

      I had to remove almost every user input error detector because the regex isn't right.

      I use these 5 example ship positions C2 G6 B1 F5 D3

      It has alot of problems so hack at your own minds risk :)

      #!/usr/bin/perl # # Battleship.pl # only one hit sinks a ship # run from command prompt at C:\Users>perl battleship.pl enter # From www.perlmonks.com # ##use v5.006; ##use strict; ##use warnings; &startup(); #********************************************************************* +********* #*******************************STARTUP FUNCTION********************** +********* #********************************************************************* +********* sub main::startup () { local $main::startup::name = ""; print "\n\nPlease enter your name: "; chomp($main::startup::name = <STDIN>); &main::call; } #********************************************************************* +********** #******************************MAIN CALL FUNCTION********************* +********** #********************************************************************* +********** sub main::call () { srand; local @main::com_ships::com_all_ships = (); local @main::com_ships::com_carrier = (); local @main::com_ships::com_battleship = (); local @main::com_ships::com_destroyer = (); local @main::com_ships::com_submarine = (); local @main::com_ships::com_patrol = (); local @main::user_ships::user_all_ships = (); local @main::user_ships::user_carrier = (); local @main::user_ships::user_battleship = (); local @main::user_ships::user_destroyer = (); local @main::user_ships::user_submarine = (); local @main::user_ships::user_patrol = (); local @main::com_ships::com_board = ( [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], ); local @main::user_ships::user_board = ( [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], ); local @main::letters::letters = ("A" .. "J"); local $main::game_play::whos_first = ''; local $main::game_play::mode = ''; local @main::game_play::com_shots_check; local @main::game_play::user_shots_check; local $main::com_ships::hits = ''; local $main::user_ships::hits = ''; &generate_ship_pos::start(); &get_user_ship_pos::start(); &game_play::start(); } #********************************************************************* +********** #***************************SECONDARY CALL FUNCTIONS****************** +********** #********************************************************************* +********** sub generate_ship_pos::start () { &generate_ship_pos::carrier(); &generate_ship_pos::battleship(); &generate_ship_pos::destroyer(); &generate_ship_pos::submarine(); &generate_ship_pos::patrol(); &generate_ship_pos::correctional(@main::com_ships::com_all_ships); } sub get_user_ship_pos::start () { &get_user_ship_pos::carrier(); &get_user_ship_pos::battleship(); &get_user_ship_pos::destroyer(); &get_user_ship_pos::submarine(); &get_user_ship_pos::patrol(); } sub game_play::start () { $main::game_play::whos_first = &game_play::decide(); $main::game_play::mode = &game_play::mode(); &game_play::tree_branches($main::game_play::whos_first, $main::game_p +lay::mode); } #********************************************************************* +********** #*********************COMPUTER SHIP GENERATION FUNCTIONS************** +********** #********************************************************************* +********** sub generate_ship_pos::carrier () { while (@main::com_ships::com_carrier != 5) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_carrier = ("$x" . "$y", "$x" . "$y"+1, +"$x" . "$y"+2, "$x" . "$y"+3, "$x" . "$y"+4); } if ($y > 2 and $y <= 6) { @main::com_ships::com_carrier = ("$x" . "$y"-2, "$x" . "$y"-1 +, "$x" . "$y", "$x" . "$y"+1, "$x" . "$y"+2); } if ($y > 6) { @main::com_ships::com_carrier = ("$x" . "$y"-4, "$x" . "$y"-3 +, "$x" . "$y"-2, "$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_carrier = ("$x" . "$y", "$x"+1 . "$y", +"$x"+2 . "$y", "$x"+3 . "$y", "$x"+4 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_carrier = ("$x"-2 . "$y", "$x"-1 . "$y" +, "$x" . "$y", "$x"+1 . "$y", "$x"+2 . "$y"); } if ($x > 6) { @main::com_ships::com_carrier = ("$x"-4 . "$y", "$x"-3 . "$y" +, "$x"-2 . "$y", "$x"-1 . "$y", "$x" . "$y"); } } push @main::com_ships::com_all_ships, @main::com_ships::com_carrier +; } } sub generate_ship_pos::battleship () { while (@main::com_ships::com_battleship != 4) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_battleship = ("$x" . "$y", "$x" . "$y"+ +1, "$x" . "$y"+2, "$x" . "$y"+3); } if ($y > 2 and $y <= 6) { @main::com_ships::com_battleship = ("$x" . "$y"-2, "$x" . "$y +"-1, "$x" . "$y", "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_battleship = ("$x" . "$y"-3, "$x" . "$y +"-2, "$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_battleship = ("$x" . "$y", "$x"+1 . "$y +", "$x"+2 . "$y", "$x"+3 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_battleship = ("$x"-2 . "$y", "$x"-1 . " +$y", "$x" . "$y", "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_battleship = ("$x"-3 . "$y", "$x"-2 . " +$y", "$x"-1 . "$y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_battleship) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_battleship = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_battle +ship; } } sub generate_ship_pos::destroyer () { while (@main::com_ships::com_destroyer != 3) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_destroyer = ("$x" . "$y", "$x" . "$y"+1 +, "$x" . "$y"+2); } if ($y > 2 and $y <= 6) { @main::com_ships::com_destroyer = ("$x" . "$y"-1, "$x" . "$y" +, "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_destroyer = ("$x" . "$y"-2, "$x" . "$y" +-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_destroyer = ("$x" . "$y", "$x"+1 . "$y" +, "$x"+2 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_destroyer = ("$x"-1 . "$y", "$x" . "$y" +, "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_destroyer = ("$x"-2 . "$y", "$x"-1 . "$ +y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_destroyer) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_destroyer = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_destro +yer; } } sub generate_ship_pos::submarine () { while (@main::com_ships::com_submarine != 3) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_submarine = ("$x" . "$y", "$x" . "$y"+1 +, "$x" . "$y"+2); } if ($y > 2 and $y <= 6) { @main::com_ships::com_submarine = ("$x" . "$y"-1, "$x" . "$y" +, "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_submarine = ("$x" . "$y"-2, "$x" . "$y" +-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_submarine = ("$x" . "$y", "$x"+1 . "$y" +, "$x"+2 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_submarine = ("$x"-1 . "$y", "$x" . "$y" +, "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_submarine = ("$x"-2 . "$y", "$x"-1 . "$ +y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_submarine) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_submarine = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_submar +ine; } } sub generate_ship_pos::patrol () { while (@main::com_ships::com_patrol != 2) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_patrol = ("$x" . "$y", "$x" . "$y"+1); } if ($y > 2 and $y <= 6) { @main::com_ships::com_patrol = ( "$x" . "$y", "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_patrol = ("$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_patrol = ("$x" . "$y", "$x"+1 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_patrol = ("$x" . "$y", "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_patrol = ("$x"-1 . "$y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_patrol) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_patrol = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_patrol +; } } sub generate_ship_pos::correctional() { foreach my $el (@main::com_ships::com_all_ships) { if (length $el == 1) { $el = '0' . "$el"; } } } #********************************************************************* +********** #************************USER SHIP GENERATION FUNCTIONS*************** +********** #********************************************************************* +********** sub get_user_ship_pos::carrier () { my @user_carrier_check_let = (); my @user_carrier_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your carrier positions (e.g. C2): "; chomp($input = <STDIN>); print $input, "inputted", "\n"; @main::user_ships::user_carrier = split("", $input); print @main::user_ships::user_carrier, "carrier input", "\n"; foreach my $el (@main::user_ships::user_carrier) { ### use C2 as ex +ample my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "C") { $let = 2; ### gdk edit } my $num = 0; if ($two == 2) { ### if ne to a letter else a number so $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### gdk edit warning push @user_carrier_check_let, $let; push @user_carrier_check_num, $num; } @user_carrier_check_let = sort {$a <=> $b} @user_carrier_check_let; @user_carrier_check_num = sort {$a <=> $b} @user_carrier_check_num; my $string_alet = $user_carrier_check_let[0] . $user_carrier_check_le +t[1] . $user_carrier_check_let[2] . $user_carrier_check_let[3] . $use +r_carrier_check_let[4]; my $string_anum = $user_carrier_check_num[0] . $user_carrier_check_nu +m[1] . $user_carrier_check_num[2] . $user_carrier_check_num[3] . $use +r_carrier_check_num[4]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_carrier) { my ($let) = split('', $el); ### gdk edit my ($num) = split('', $el); ### gdk edit $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_carri +er; } sub get_user_ship_pos::battleship () { my @user_battleship_check_let = (); my @user_battleship_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your battleship positions (e.g. G6): "; chomp($input = <STDIN>); @main::user_ships::user_battleship = split("", $input); foreach my $el (@main::user_ships::user_battleship) { ### use G6 a +s example my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "G") { $let = 6; ### gdk edit } my $num = 0; if ($two == 6) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### gdk edit warning push @user_battleship_check_let, $let; push @user_battleship_check_num, $num; } @user_battleship_check_let = sort {$a <=> $b} @user_battleship_check_ +let; @user_battleship_check_num = sort {$a <=> $b} @user_battleship_check_ +num; my $string_alet = $user_battleship_check_let[0] . $user_battleship_ch +eck_let[1] . $user_battleship_check_let[2] . $user_battleship_check_l +et[3]; my $string_anum = $user_battleship_check_num[0] . $user_battleship_ch +eck_num[1] . $user_battleship_check_num[2] . $user_battleship_check_n +um[3]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_battleship) { my ($let) = split('', $el); ### gdk edit my ($num) = split('', $el); ### gdk edit $main::user_ships::user_board[$let][$num] = "*"; } push @main::user_ships::user_all_ships, @main::user_ships::user_battl +eship; } sub get_user_ship_pos::destroyer () { my @user_destroyer_check_let = (); my @user_destroyer_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your destroyer positions (e.g. B1): "; chomp($input = <STDIN>); @main::user_ships::user_destroyer = split("", $input); foreach my $el (@main::user_ships::user_destroyer) { my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "B") { $let = 1; ### gdk edit } my $num = 0; if ($two == 1) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### GDK warning push @user_destroyer_check_let, $let; push @user_destroyer_check_num, $num; } @user_destroyer_check_let = sort {$a <=> $b} @user_destroyer_check_le +t; @user_destroyer_check_num = sort {$a <=> $b} @user_destroyer_check_nu +m; my $string_alet = $user_destroyer_check_let[0] . $user_destroyer_chec +k_let[1] . $user_destroyer_check_let[2]; my $string_anum = $user_destroyer_check_num[0] . $user_destroyer_chec +k_num[1] . $user_destroyer_check_num[2]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_destroyer) { my ($let) = split('', $el); ### gdk edit my ($num) = split('', $el); ### gdk edit $main::user_ships::user_board[$let][$num] = "%"; } push @main::user_ships::user_all_ships, @main::user_ships::user_destr +oyer; } sub get_user_ship_pos::submarine () { my @user_submarine_check_let = (); my @user_submarine_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your submarine positions (e.g. F5): "; chomp($input = <STDIN>); @main::user_ships::user_submarine = split("", $input); foreach my $el (@main::user_ships::user_submarine) { my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "F") { $let = 5; ### gdk edit } my $num = 0; if ($two == 5) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ## GDK warning push @user_submarine_check_let, $let; push @user_submarine_check_num, $num; } @user_submarine_check_let = sort {$a <=> $b} @user_submarine_check_le +t; @user_submarine_check_num = sort {$a <=> $b} @user_submarine_check_nu +m; my $string_alet = $user_submarine_check_let[0] . $user_submarine_chec +k_let[1] . $user_submarine_check_let[2]; my $string_anum = $user_submarine_check_num[0] . $user_submarine_chec +k_num[1] . $user_submarine_check_num[2]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_submarine) { my ($let) = split('', $el); ### gdk edit my ($num) = split('', $el); ### gdk edit $main::user_ships::user_board[$let][$num] = "^"; } push @main::user_ships::user_all_ships, @main::user_ships::user_subma +rine; } sub get_user_ship_pos::patrol () { my @user_patrol_check_let = (); my @user_patrol_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your patrol positions (e.g. D3):"; chomp($input = <STDIN>); @main::user_ships::user_patrol = split("", $input); foreach my $el (@main::user_ships::user_patrol) { my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "D") { $let = 3; ### gdk edit } my $num = 0; if ($two == 3) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### GDK warning push @user_patrol_check_let, $let; push @user_patrol_check_num, $num; } @user_patrol_check_let = sort {$a <=> $b} @user_patrol_check_let; @user_patrol_check_num = sort {$a <=> $b} @user_patrol_check_num; my $string_alet = $user_patrol_check_let[0] . $user_patrol_check_let[ +1]; my $string_anum = $user_patrol_check_num[0] . $user_patrol_check_num[ +1]; print $user_patrol_check_let[0], $user_patrol_check_let[1], $user_patr +ol_check_num[0], $user_patrol_check_num[1], "patrol", "\n"; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_patrol) { my ($let) = split('', $el); ### gdk edit my ($num) = split('', $el); ### gdk edit $main::user_ships::user_board[$let][$num] = "~"; } push @main::user_ships::user_all_ships, @main::user_ships::user_patro +l; } #********************************************************************* +********** #*******************************GAME-PLAY FUNCTIONS******************* +********** #********************************************************************* +********** sub game_play::decide () { my $decide = ''; while (!$decide) { print "\n1. You ($main::startup::name)"; print "\n2. Computer"; print "\n3. Random"; print "\n\nPlease enter digit to decide who goes first: "; chomp($decide = <STDIN>); if ($decide == 1 or $decide == 2) { return $decide; } elsif ($decide = 3) { return int(rand(1000)); } else { print "Your slection is not recognized. Please try again.\n"; $decide = ''; } } } sub game_play::mode () { my $mode = ''; while (!$mode) { print "\n1. Regular"; print "\n2. Three-shot salvo"; print "\n\nPlease enter mode selection: "; chomp($mode = <STDIN>); if ($mode == 1 or $mode == 2) { return $mode; } else { print "Your slection is not recognized. Please try again.\n"; $mode = ''; } } } sub game_play::tree_branches () { my @deciders = @_; if ($deciders[0]/2 == int($deciders[0]/2)){ &game_play::com_start($deciders[1]); } else { &game_play::user_start($deciders[1]); } } sub game_play::com_start () { my ($decider) = @_; print "COMPUTER STARTS . . . .\n\n"; sleep 1; if ($decider == 2) { &game_play::com_start::salvo_mode(); } elsif ($decider == 1) { &game_play::com_start::reg_mode(); } } sub game_play::user_start () { my ($decider) = @_; print "$main::startup::name STARTS . . . .\n\n"; if ($decider == 2) { &game_play::user_start::salvo_mode(); } else { &game_play::user_start::reg_mode(); } } sub game_play::com_start::salvo_mode() { while (!&game_play::dead_yet()) { &game_play::salvo_mode::com_salvo(); &game_play::dead_yet(); print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::salvo_mode::user_salvo(); &game_play::dead_yet(); } } sub game_play::com_start::reg_mode() { while (!&game_play::dead_yet()) { &game_play::reg_mode::com_shot(); &game_play::dead_yet(); print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::reg_mode::user_shot(); &game_play::dead_yet(); } } sub game_play::user_start::salvo_mode() { while (!&game_play::dead_yet()) { print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::salvo_mode::user_salvo(); &game_play::dead_yet(); &game_play::salvo_mode::com_salvo(); &game_play::dead_yet(); } } sub game_play::user_start::reg_mode() { while (!&game_play::dead_yet()) { print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "COMPUTER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; print " --------------------\n"; $i = 0; foreach my $el (@main::com_ships::com_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } &game_play::reg_mode::user_shot(); &game_play::dead_yet(); &game_play::reg_mode::com_shot(); &game_play::dead_yet(); } } sub game_play::salvo_mode::com_salvo () { my $x1 = int(rand(10)); my $y1 = int(rand(10)); my $x2 = int(rand(10)); my $y2 = int(rand(10)); my $x3 = int(rand(10)); my $y3 = int(rand(10)); my @temp_checker = ("$x1" . "$y1", "$x2" . "$y2", "$x3" . "$y3"); if (($main::user_ships::user_board[$x1][$y1] eq 'X') or ($main::user_ +ships::user_board[$x1][$y1] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } if (($main::user_ships::user_board[$x3][$y3] eq 'X') or ($main::user_ +ships::user_board[$x3][$y3] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } if (($main::user_ships::user_board[$x2][$y2] eq 'X') or ($main::user_ +ships::user_board[$x2][$y2] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } push @main::game_play::com_shots_check, @temp_checker; if (($main::user_ships::user_board[$x1][$y1] eq '#') or ($main::user_ +ships::user_board[$x1][$y1] eq '*') or ($main::user_ships::user_board +[$x1][$y1] eq '%') or ($main::user_ships::user_board[$x1][$y1] eq '~' +) or ($main::user_ships::user_board[$x1][$y1] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x1][$y1] = 'X'; } elsif ($main::user_ships::user_board[$x1][$y1] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x1][$y1] = 'O'; } if (($main::user_ships::user_board[$x2][$y2] eq '#') or ($main::user_s +hips::user_board[$x2][$y2] eq '*') or ($main::user_ships::user_board[ +$x2][$y2] eq '%') or ($main::user_ships::user_board[$x2][$y2] eq '~') + or ($main::user_ships::user_board[$x2][$y2] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x2][$y2] = 'X'; } elsif ($main::user_ships::user_board[$x2][$y2] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x2][$y2] = 'O'; } if (($main::user_ships::user_board[$x3][$y3] eq '#') or ($main::user_s +hips::user_board[$x3][$y3] eq '*') or ($main::user_ships::user_board[ +$x3][$y3] eq '%') or ($main::user_ships::user_board[$x3][$y3] eq '~') + or ($main::user_ships::user_board[$x3][$y3] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x3][$y3] = 'X'; } elsif ($main::user_ships::user_board[$x3][$y3] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x3][$y3] = 'O'; } } sub game_play::salvo_mode::user_salvo () { my $input = ''; print "\n Please enter your three salvo shots (e.g. A4 B6 F4):"; chomp($input = <STDIN>); my @user_shots = split(" ", $input); if ($input !~ /^[A-J]\d0?\s[A-J]\d0?\s[A-J]\d0?$/i) { print "You've entered invalid salvo shot. Please try again.\n"; &game_play::salvo_mode::user_salvo(); return 0; } if ($user_shots[0] eq ($user_shots[1] or $user_shots[2]) or $user_sho +ts[1] eq $user_shots[2]) { print "You have entered a co-ordinate twice. Please try again.\n"; &game_play::salvo_mode::user_salvo(); return 0; } foreach my $el (@user_shots) { my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit if ($el eq "A") { $let = 0; ### gdk edit } if ($el eq "B") { $let = 1; ### gdk edit } if ($el eq "C") { $let = 2; ### gdk edit } if ($el eq "D") { $let = 3; ### gdk edit } if ($el eq "E") { $let = 4; ### gdk edit } if ($el eq "F") { $let = 5; ### gdk edit } if ($el eq "G") { $let = 6; ### gdk edit } if ($el eq "H") { $let = 7; ### gdk edit } if ($el eq "I") { $let = 8; ### gdk edit } if ($el eq "J") { $let = 9; ### gdk edit } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; ### GDK warning foreach my $lee (@main::game_play::user_shots_check) { if ($el eq $lee) { print "You have entered invalid user shot. Please try again. +\n"; &game_play::salvo_mode::user_salvo(); return; } } foreach my $lee (@main::com_ships::com_all_ships) { if ($el eq $lee) { print "Computer ship hit!\n"; $main::com_ships::com_board[$let][$num] = 'X'; $main::com_ships::hits++; last; } elsif ($el ne $lee) { $main::com_ships::com_board[$let][$num] = 'O'; } } } push @main::game_play::user_shots_check, @user_shots; } sub game_play::reg_mode::com_shot () { my $x1 = int(rand(10)); my $y1 = int(rand(10)); my $temp_checker = ("$x1" . "$y1"); if (($main::user_ships::user_board[$x1][$y1] eq 'X') or ($main::user_ +ships::user_board[$x1][$y1] eq 'O')) { &game_play::reg_mode::com_shot; ### all ships were already hit an +d the last choice by computer caused error: out of memory! attempt to + free unreferenced scalar at battleship.pl line 938, <STDIN> line 117 +. return; } push @main::game_play::com_shots_check, $temp_checker; if (($main::user_ships::user_board[$x1][$y1] eq '#') or ($main::user_ +ships::user_board[$x1][$y1] eq '*') or ($main::user_ships::user_board +[$x1][$y1] eq '%') or ($main::user_ships::user_board[$x1][$y1] eq '~' +) or ($main::user_ships::user_board[$x1][$y1] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $main::user_ships::user_board[$x1][$y1] = 'X'; } elsif ($main::user_ships::user_board[$x1][$y1] eq 'X') { &game_play::reg_mode::com_shot; return; } else { $main::user_ships::user_board[$x1][$y1] = 'O'; } } sub game_play::reg_mode::user_shot () { my $input = ''; my $choosen = ''; print "\n Please enter your target: "; chomp($input = <STDIN>); $choosen = $input; my @target_choice = split("", $input); if ($input !~ /^[A-J]\d0?$/i) { print "You've entered invalid target. Please try again.\n"; &game_play::reg_mode::user_shot(); return 0; } foreach my $el (@target_choice) { my ($let) = split('', $el); ## gdk edit my ($one) = split('', $el); ## gdk edit my ($two) = split('', $el); ## gdk edit if ($el eq "A") { $let = 0; ### gdk edit } if ($el eq "B") { $let = 1; ### gdk edit } if ($el eq "C") { $let = 2; ### gdk edit } if ($el eq "D") { $let = 3; ### gdk edit } if ($el eq "E") { $let = 4; ### gdk edit } if ($el eq "F") { $let = 5; ### gdk edit } if ($el eq "G") { $let = 6; ### gdk edit } if ($el eq "H") { $let = 7; ### gdk edit } if ($el eq "I") { $let = 8; ### gdk edit } if ($el eq "J") { $let = 9; ### gdk edit } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $input = "$let" . "$num"; print $el, "el again", "\n"; } ### gdk warning foreach my $lee (@main::game_play::user_shots_check) { if ($choosen eq $lee) { print "You have entered invalid shot check. Please try again.\n" +; &game_play::reg_mode::user_shot(); return; } } foreach my $lee (@main::com_ships::com_all_ships) { if ($choosen eq $lee) { print "Computer ship hit!\n"; $main::com_ships::com_board[$let][$num] = 'X'; $main::com_ships::hits++; last; } elsif ($choosen ne $lee) { $main::com_ships::com_board[$let][$num] = 'O'; } } push @main::game_play::user_shots_check, $el; } sub game_play::dead_yet () { if ($main::com_ships::hits eq '17') { &game_play::end_game(2); } if ($main::user_ships::hits eq '17') { &game_play::end_game(1); } } sub game_play::end_game () { my @winner = @_; if ($winner[0] == 2) { print "Congratulations! You won, $main::startup::name!\n\n"; exit; } else { print "Computer won. Better luck next time!\n"; exit; } } sub game_play::THE_END () { print "\n"; }

        Ok now this is way better

        There is always a satellite at A1

        Object is to make the computer use the most shots of two plays

        The 6 objects are always in the same place

        Use caps or lower case letters ok

        Use Salvo for quicker games

        #!/usr/bin/perl # # Battleship.pl # only one hit sinks a ship # run from command prompt at C:\Users>perl battleship.pl enter # From www.perlmonks.com # a satellite is always at A1 ##use v5.10.1; ##use strict; ##use warnings; ##use strict; &startup(); #********************************************************************* +********* #*******************************STARTUP FUNCTION********************** +********* #********************************************************************* +********* sub main::startup () { local $main::startup::name = ""; print "\n\nPlease enter your name: "; chomp($main::startup::name = <STDIN>); &main::call; } my $pausetillenter = ""; my $countshots = 1; #********************************************************************* +********** #******************************MAIN CALL FUNCTION********************* +********** #********************************************************************* +********** sub main::call () { srand; local @main::com_ships::com_all_ships = (); local @main::com_ships::com_carrier = (); local @main::com_ships::com_battleship = (); local @main::com_ships::com_destroyer = (); local @main::com_ships::com_submarine = (); local @main::com_ships::com_patrol = (); local @main::user_ships::user_all_ships = (); local @main::user_ships::user_carrier = (); local @main::user_ships::user_battleship = (); local @main::user_ships::user_destroyer = (); local @main::user_ships::user_submarine = (); local @main::user_ships::user_patrol = (); local @main::com_ships::com_board = ( [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], ); local @main::user_ships::user_board = ( [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0,0,0], ); local @main::letters::letters = ("A" .. "J"); local $main::game_play::whos_first = ''; local $main::game_play::mode = ''; local @main::game_play::com_shots_check; local @main::game_play::user_shots_check; local $main::com_ships::hits = ''; local $main::user_ships::hits = ''; &generate_ship_pos::start(); &get_user_ship_pos::start(); &game_play::start(); } #********************************************************************* +********** #***************************SECONDARY CALL FUNCTIONS****************** +********** #********************************************************************* +********** sub generate_ship_pos::start () { &generate_ship_pos::carrier(); &generate_ship_pos::battleship(); &generate_ship_pos::destroyer(); &generate_ship_pos::submarine(); &generate_ship_pos::patrol(); &generate_ship_pos::correctional(@main::com_ships::com_all_ships); } sub get_user_ship_pos::start () { &get_user_ship_pos::carrier(); &get_user_ship_pos::battleship(); &get_user_ship_pos::destroyer(); &get_user_ship_pos::submarine(); &get_user_ship_pos::patrol(); } sub game_play::start () { $main::game_play::whos_first = &game_play::decide(); $main::game_play::mode = &game_play::mode(); &game_play::tree_branches($main::game_play::whos_first, $main::game_p +lay::mode); } #********************************************************************* +********** #*********************COMPUTER SHIP GENERATION FUNCTIONS************** +********** #********************************************************************* +********** sub generate_ship_pos::carrier () { while (@main::com_ships::com_carrier != 5) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_carrier = ("$x" . "$y", "$x" . "$y"+1, +"$x" . "$y"+2, "$x" . "$y"+3, "$x" . "$y"+4); } if ($y > 2 and $y <= 6) { @main::com_ships::com_carrier = ("$x" . "$y"-2, "$x" . "$y"-1 +, "$x" . "$y", "$x" . "$y"+1, "$x" . "$y"+2); } if ($y > 6) { @main::com_ships::com_carrier = ("$x" . "$y"-4, "$x" . "$y"-3 +, "$x" . "$y"-2, "$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_carrier = ("$x" . "$y", "$x"+1 . "$y", +"$x"+2 . "$y", "$x"+3 . "$y", "$x"+4 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_carrier = ("$x"-2 . "$y", "$x"-1 . "$y" +, "$x" . "$y", "$x"+1 . "$y", "$x"+2 . "$y"); } if ($x > 6) { @main::com_ships::com_carrier = ("$x"-4 . "$y", "$x"-3 . "$y" +, "$x"-2 . "$y", "$x"-1 . "$y", "$x" . "$y"); } } push @main::com_ships::com_all_ships, @main::com_ships::com_carrier +; } } sub generate_ship_pos::battleship () { while (@main::com_ships::com_battleship != 4) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_battleship = ("$x" . "$y", "$x" . "$y"+ +1, "$x" . "$y"+2, "$x" . "$y"+3); } if ($y > 2 and $y <= 6) { @main::com_ships::com_battleship = ("$x" . "$y"-2, "$x" . "$y +"-1, "$x" . "$y", "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_battleship = ("$x" . "$y"-3, "$x" . "$y +"-2, "$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_battleship = ("$x" . "$y", "$x"+1 . "$y +", "$x"+2 . "$y", "$x"+3 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_battleship = ("$x"-2 . "$y", "$x"-1 . " +$y", "$x" . "$y", "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_battleship = ("$x"-3 . "$y", "$x"-2 . " +$y", "$x"-1 . "$y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_battleship) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_battleship = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_battle +ship; } } sub generate_ship_pos::destroyer () { while (@main::com_ships::com_destroyer != 3) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_destroyer = ("$x" . "$y", "$x" . "$y"+1 +, "$x" . "$y"+2); } if ($y > 2 and $y <= 6) { @main::com_ships::com_destroyer = ("$x" . "$y"-1, "$x" . "$y" +, "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_destroyer = ("$x" . "$y"-2, "$x" . "$y" +-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_destroyer = ("$x" . "$y", "$x"+1 . "$y" +, "$x"+2 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_destroyer = ("$x"-1 . "$y", "$x" . "$y" +, "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_destroyer = ("$x"-2 . "$y", "$x"-1 . "$ +y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_destroyer) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_destroyer = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_destro +yer; } } sub generate_ship_pos::submarine () { while (@main::com_ships::com_submarine != 3) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_submarine = ("$x" . "$y", "$x" . "$y"+1 +, "$x" . "$y"+2); } if ($y > 2 and $y <= 6) { @main::com_ships::com_submarine = ("$x" . "$y"-1, "$x" . "$y" +, "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_submarine = ("$x" . "$y"-2, "$x" . "$y" +-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_submarine = ("$x" . "$y", "$x"+1 . "$y" +, "$x"+2 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_submarine = ("$x"-1 . "$y", "$x" . "$y" +, "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_submarine = ("$x"-2 . "$y", "$x"-1 . "$ +y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_submarine) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_submarine = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_submar +ine; } } sub generate_ship_pos::patrol () { while (@main::com_ships::com_patrol != 2) { my $x = int(rand(9)); my $y = int(rand(9)); my $orient = int(rand(1000)); if ($orient < 500) { if ($y <= 2) { @main::com_ships::com_patrol = ("$x" . "$y", "$x" . "$y"+1); } if ($y > 2 and $y <= 6) { @main::com_ships::com_patrol = ( "$x" . "$y", "$x" . "$y"+1); } if ($y > 6) { @main::com_ships::com_patrol = ("$x" . "$y"-1, "$x" . "$y"); } } if ($orient > 500) { if ($x <= 2) { @main::com_ships::com_patrol = ("$x" . "$y", "$x"+1 . "$y"); } if ($x > 2 and $x <= 6) { @main::com_ships::com_patrol = ("$x" . "$y", "$x"+1 . "$y"); } if ($x > 6) { @main::com_ships::com_patrol = ("$x"-1 . "$y", "$x" . "$y"); } } foreach my $el (@main::com_ships::com_all_ships) { foreach my $lee (@main::com_ships::com_patrol) { if (($lee + 1 == $el) or ($lee - 1 == $el) or ($lee + 10 == $ +el) or ($lee - 10 == $el)) { @main::com_ships::com_patrol = (); last; } } } push @main::com_ships::com_all_ships, @main::com_ships::com_patrol +; } } sub generate_ship_pos::correctional() { foreach my $el (@main::com_ships::com_all_ships) { if (length $el == 1) { $el = '0' . "$el"; } } } #********************************************************************* +********** #************************USER SHIP GENERATION FUNCTIONS*************** +********** #********************************************************************* +********** sub get_user_ship_pos::carrier () { my @user_carrier_check_let = (); my @user_carrier_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your carrier positions (e.g. C2): "; chomp($input = <STDIN>); print $input, "inputted", "\n"; @main::user_ships::user_carrier = split("", $input); print @main::user_ships::user_carrier, "carrier input", "\n"; foreach my $el (@main::user_ships::user_carrier) { ### use C2 as ex +ample my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "C") { $let = 2; ### ss edit } my $num = 0; if ($two == 2) { ### if ne to a letter else a number so $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### ss edit warning push @user_carrier_check_let, $let; push @user_carrier_check_num, $num; } @user_carrier_check_let = sort {$a <=> $b} @user_carrier_check_let; @user_carrier_check_num = sort {$a <=> $b} @user_carrier_check_num; my $string_alet = $user_carrier_check_let[0] . $user_carrier_check_le +t[1] . $user_carrier_check_let[2] . $user_carrier_check_let[3] . $use +r_carrier_check_let[4]; my $string_anum = $user_carrier_check_num[0] . $user_carrier_check_nu +m[1] . $user_carrier_check_num[2] . $user_carrier_check_num[3] . $use +r_carrier_check_num[4]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_carrier) { my ($let) = split('', $el); ### ss edit my ($num) = split('', $el); ### ss edit $main::user_ships::user_board[$let][$num] = "#"; } push @main::user_ships::user_all_ships, @main::user_ships::user_carri +er; } sub get_user_ship_pos::battleship () { my @user_battleship_check_let = (); my @user_battleship_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your battleship positions (e.g. G6): "; chomp($input = <STDIN>); @main::user_ships::user_battleship = split("", $input); foreach my $el (@main::user_ships::user_battleship) { ### use G6 a +s example my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "G") { $let = 6; ### ss edit } my $num = 0; if ($two == 6) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### ss edit warning push @user_battleship_check_let, $let; push @user_battleship_check_num, $num; } @user_battleship_check_let = sort {$a <=> $b} @user_battleship_check_ +let; @user_battleship_check_num = sort {$a <=> $b} @user_battleship_check_ +num; my $string_alet = $user_battleship_check_let[0] . $user_battleship_ch +eck_let[1] . $user_battleship_check_let[2] . $user_battleship_check_l +et[3]; my $string_anum = $user_battleship_check_num[0] . $user_battleship_ch +eck_num[1] . $user_battleship_check_num[2] . $user_battleship_check_n +um[3]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_battleship) { my ($let) = split('', $el); ### ss edit my ($num) = split('', $el); ### ss edit $main::user_ships::user_board[$let][$num] = "*"; } push @main::user_ships::user_all_ships, @main::user_ships::user_battl +eship; } sub get_user_ship_pos::destroyer () { my @user_destroyer_check_let = (); my @user_destroyer_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your destroyer positions (e.g. B1): "; chomp($input = <STDIN>); @main::user_ships::user_destroyer = split("", $input); foreach my $el (@main::user_ships::user_destroyer) { my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "B") { $let = 1; ### ss edit } my $num = 0; if ($two == 1) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### ss warning push @user_destroyer_check_let, $let; push @user_destroyer_check_num, $num; } @user_destroyer_check_let = sort {$a <=> $b} @user_destroyer_check_le +t; @user_destroyer_check_num = sort {$a <=> $b} @user_destroyer_check_nu +m; my $string_alet = $user_destroyer_check_let[0] . $user_destroyer_chec +k_let[1] . $user_destroyer_check_let[2]; my $string_anum = $user_destroyer_check_num[0] . $user_destroyer_chec +k_num[1] . $user_destroyer_check_num[2]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_destroyer) { my ($let) = split('', $el); ### ss edit my ($num) = split('', $el); ### ss edit $main::user_ships::user_board[$let][$num] = "%"; } push @main::user_ships::user_all_ships, @main::user_ships::user_destr +oyer; } sub get_user_ship_pos::submarine () { my @user_submarine_check_let = (); my @user_submarine_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your submarine positions (e.g. F5): "; chomp($input = <STDIN>); @main::user_ships::user_submarine = split("", $input); foreach my $el (@main::user_ships::user_submarine) { my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "F") { $let = 5; ### ss edit } my $num = 0; if ($two == 5) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ## ss warning push @user_submarine_check_let, $let; push @user_submarine_check_num, $num; } @user_submarine_check_let = sort {$a <=> $b} @user_submarine_check_le +t; @user_submarine_check_num = sort {$a <=> $b} @user_submarine_check_nu +m; my $string_alet = $user_submarine_check_let[0] . $user_submarine_chec +k_let[1] . $user_submarine_check_let[2]; my $string_anum = $user_submarine_check_num[0] . $user_submarine_chec +k_num[1] . $user_submarine_check_num[2]; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_submarine) { my ($let) = split('', $el); ### ss edit my ($num) = split('', $el); ### ss edit $main::user_ships::user_board[$let][$num] = "^"; } push @main::user_ships::user_all_ships, @main::user_ships::user_subma +rine; } sub get_user_ship_pos::patrol () { my @user_patrol_check_let = (); my @user_patrol_check_num = (); my $input = ''; my $decide = 1; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } print "Please enter your patrol positions (e.g. D3):"; chomp($input = <STDIN>); @main::user_ships::user_patrol = split("", $input); foreach my $el (@main::user_ships::user_patrol) { my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit print $el, "el", $one, "one", $two, "two", "\n"; if ($el eq "D") { $let = 3; ### ss edit } my $num = 0; if ($two == 3) { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; print $el, "el again", "\n"; ### ss warning push @user_patrol_check_let, $let; push @user_patrol_check_num, $num; } @user_patrol_check_let = sort {$a <=> $b} @user_patrol_check_let; @user_patrol_check_num = sort {$a <=> $b} @user_patrol_check_num; my $string_alet = $user_patrol_check_let[0] . $user_patrol_check_let[ +1]; my $string_anum = $user_patrol_check_num[0] . $user_patrol_check_num[ +1]; print $user_patrol_check_let[0], $user_patrol_check_let[1], $user_patr +ol_check_num[0], $user_patrol_check_num[1], "patrol", "\n"; print $string_alet, " alet ", $string_anum, " anum", "\n"; foreach my $el (@main::user_ships::user_patrol) { my ($let) = split('', $el); ### ss edit my ($num) = split('', $el); ### ss edit $main::user_ships::user_board[$let][$num] = "~"; } push @main::user_ships::user_all_ships, @main::user_ships::user_patro +l; } #********************************************************************* +********** #*******************************GAME-PLAY FUNCTIONS******************* +********** #********************************************************************* +********** sub game_play::decide () { my $decide = ''; while (!$decide) { print "\n1. You ($main::startup::name)"; print "\n2. Computer"; print "\n3. Random"; print "\n\nPlease enter digit to decide who goes first: "; chomp($decide = <STDIN>); if ($decide == 1 or $decide == 2) { return $decide; } elsif ($decide = 3) { return int(rand(1000)); } else { print "Your slection is not recognized. Please try again.\n"; $decide = ''; } } } sub game_play::mode () { my $mode = ''; while (!$mode) { print "\n1. Regular"; print "\n2. Three-shot salvo"; print "\n\nPlease enter mode selection: "; chomp($mode = <STDIN>); if ($mode == 1 or $mode == 2) { return $mode; } else { print "Your slection is not recognized. Please try again.\n"; $mode = ''; } } } sub game_play::tree_branches () { my @deciders = @_; if ($deciders[0]/2 == int($deciders[0]/2)){ &game_play::com_start($deciders[1]); } else { &game_play::user_start($deciders[1]); } } sub game_play::com_start () { my ($decider) = @_; print "COMPUTER STARTS . . . .\n\n"; sleep 1; if ($decider == 2) { &game_play::com_start::salvo_mode(); } elsif ($decider == 1) { &game_play::com_start::reg_mode(); } } sub game_play::user_start () { my ($decider) = @_; print "$main::startup::name STARTS . . . .\n\n"; if ($decider == 2) { &game_play::user_start::salvo_mode(); } else { &game_play::user_start::reg_mode(); } } sub game_play::com_start::salvo_mode() { while (!&game_play::dead_yet()) { &game_play::salvo_mode::com_salvo(); &game_play::dead_yet(); print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } ## print "COMPUTER BOARD:"; ## print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; ## $i = 0; ## foreach my $el (@main::com_ships::com_board) { ## print "$main::letters::letters[$i]|"; ## print " @$el\n"; ## $i++; ## } &game_play::salvo_mode::user_salvo(); &game_play::dead_yet(); } } sub game_play::com_start::reg_mode() { while (!&game_play::dead_yet()) { &game_play::reg_mode::com_shot(); &game_play::dead_yet(); print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } ## print "COMPUTER BOARD:"; ## print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; ## $i = 0; ## foreach my $el (@main::com_ships::com_board) { ## print "$main::letters::letters[$i]|"; ## print " @$el\n"; ## $i++; ## } &game_play::reg_mode::user_shot(); &game_play::dead_yet(); } } sub game_play::user_start::salvo_mode() { while (!&game_play::dead_yet()) { print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } ## print "COMPUTER BOARD:"; ## print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; ## $i = 0; ## foreach my $el (@main::com_ships::com_board) { ## print "$main::letters::letters[$i]|"; ## print " @$el\n"; ## $i++; ## } &game_play::salvo_mode::user_salvo(); &game_play::dead_yet(); &game_play::salvo_mode::com_salvo(); &game_play::dead_yet(); } } sub game_play::user_start::reg_mode() { while (!&game_play::dead_yet()) { print "USER BOARD:"; print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; my $i = 0; foreach my $el (@main::user_ships::user_board) { print "$main::letters::letters[$i]|"; print " @$el\n"; $i++; } ## print "COMPUTER BOARD:"; ## print "\n 1 2 3 4 5 6 7 8 9 10\n"; ## print " --------------------\n"; ## $i = 0; ## foreach my $el (@main::com_ships::com_board) { ## print "$main::letters::letters[$i]|"; ## print " @$el\n"; ## $i++; ## } &game_play::reg_mode::user_shot(); &game_play::dead_yet(); &game_play::reg_mode::com_shot(); &game_play::dead_yet(); } } sub game_play::salvo_mode::com_salvo () { my $x1 = int(rand(10)); my $y1 = int(rand(10)); my $x2 = int(rand(10)); my $y2 = int(rand(10)); my $x3 = int(rand(10)); my $y3 = int(rand(10)); my @temp_checker = ("$x1" . "$y1", "$x2" . "$y2", "$x3" . "$y3"); print @temp_checker, "salvo", "\n"; if (($main::user_ships::user_board[$x1][$y1] eq 'X') or ($main::user_ +ships::user_board[$x1][$y1] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } if (($main::user_ships::user_board[$x3][$y3] eq 'X') or ($main::user_ +ships::user_board[$x3][$y3] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } if (($main::user_ships::user_board[$x2][$y2] eq 'X') or ($main::user_ +ships::user_board[$x2][$y2] eq 'O')) { &game_play::salvo_mode::com_salvo; return; } push @main::game_play::com_shots_check, @temp_checker; if (($main::user_ships::user_board[$x1][$y1] eq '#') or ($main::user_ +ships::user_board[$x1][$y1] eq '*') or ($main::user_ships::user_board +[$x1][$y1] eq '%') or ($main::user_ships::user_board[$x1][$y1] eq '~' +) or ($main::user_ships::user_board[$x1][$y1] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $countshots++; print $main::user_ships::hits, " press enter to continue", "\n"; $pausetillenter = <STDIN>; $main::user_ships::user_board[$x1][$y1] = 'X'; } elsif ($main::user_ships::user_board[$x1][$y1] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x1][$y1] = 'O'; } if (($main::user_ships::user_board[$x2][$y2] eq '#') or ($main::user_s +hips::user_board[$x2][$y2] eq '*') or ($main::user_ships::user_board[ +$x2][$y2] eq '%') or ($main::user_ships::user_board[$x2][$y2] eq '~') + or ($main::user_ships::user_board[$x2][$y2] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $countshots++; print $main::user_ships::hits, " press enter to continue", "\n"; $pausetillenter = <STDIN>; $main::user_ships::user_board[$x2][$y2] = 'X'; } elsif ($main::user_ships::user_board[$x2][$y2] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x2][$y2] = 'O'; } if (($main::user_ships::user_board[$x3][$y3] eq '#') or ($main::user_s +hips::user_board[$x3][$y3] eq '*') or ($main::user_ships::user_board[ +$x3][$y3] eq '%') or ($main::user_ships::user_board[$x3][$y3] eq '~') + or ($main::user_ships::user_board[$x3][$y3] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $countshots++; print $main::user_ships::hits, " press enter to continue", "\n"; $pausetillenter = <STDIN>; $main::user_ships::user_board[$x3][$y3] = 'X'; } elsif ($main::user_ships::user_board[$x3][$y3] eq 'X') { &game_play::salvo_mode::com_salvo; return; } else { $main::user_ships::user_board[$x3][$y3] = 'O'; } } sub game_play::salvo_mode::user_salvo () { my $input = ''; print "\n Please enter your three salvo shots (e.g. A4 B6 F4):"; chomp($input = <STDIN>); my @user_shots = split(" ", $input); if ($user_shots[0] eq ($user_shots[1] or $user_shots[2]) or $user_sho +ts[1] eq $user_shots[2]) { print "You have entered a co-ordinate twice. Please try again.\n"; &game_play::salvo_mode::user_salvo(); return 0; } $countshots++; print " shot count=", $countshots, " ", "\n"; foreach my $el (@user_shots) { my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit if ($el eq "A") { $let = 0; ### ss edit } if ($el eq "B") { $let = 1; ### ss edit } if ($el eq "C") { $let = 2; ### ss edit } if ($el eq "D") { $let = 3; ### ss edit } if ($el eq "E") { $let = 4; ### ss edit } if ($el eq "F") { $let = 5; ### ss edit } if ($el eq "G") { $let = 6; ### ss edit } if ($el eq "H") { $let = 7; ### ss edit } if ($el eq "I") { $let = 8; ### ss edit } if ($el eq "J") { $let = 9; ### ss edit } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $el = "$let" . "$num"; ### ss warning foreach my $lee (@main::com_ships::com_all_ships) { if ($el eq $lee) { print "Computer ship hit!\n"; $main::com_ships::com_board[$let][$num] = 'X'; $main::com_ships::hits++; $countshots++; print $main::com_ships::hits, " press enter to continue", "\n"; $pausetillenter = <STDIN>; last; } elsif ($el ne $lee) { $main::com_ships::com_board[$let][$num] = 'O'; } } } push @main::game_play::user_shots_check, @user_shots; } sub game_play::reg_mode::com_shot () { my $x1 = int(rand(10)); my $y1 = int(rand(10)); my $temp_checker = ("$x1" . "$y1"); if (($main::user_ships::user_board[$x1][$y1] eq 'X') or ($main::user_ +ships::user_board[$x1][$y1] eq 'O')) { &game_play::reg_mode::com_shot; ### all ships were already hit an +d the last choice by computer caused error: out of memory! attempt to + free unreferenced scalar at battleship.pl line 938, <STDIN> line 117 +. return; } push @main::game_play::com_shots_check, $temp_checker; if (($main::user_ships::user_board[$x1][$y1] eq '#') or ($main::user_ +ships::user_board[$x1][$y1] eq '*') or ($main::user_ships::user_board +[$x1][$y1] eq '%') or ($main::user_ships::user_board[$x1][$y1] eq '~' +) or ($main::user_ships::user_board[$x1][$y1] eq '^')) { print "You've been hit!\n"; $main::user_ships::hits++; $countshots++; print $main::user_ships::hits, " press enter to continue", "\n"; $pausetillenter = <STDIN>; $main::user_ships::user_board[$x1][$y1] = 'X'; } elsif ($main::user_ships::user_board[$x1][$y1] eq 'X') { &game_play::reg_mode::com_shot; return; } else { $main::user_ships::user_board[$x1][$y1] = 'O'; } } sub game_play::reg_mode::user_shot () { my $input = ''; my $choosen = ''; print "\n Please enter your target: "; chomp($input = <STDIN>); $choosen = $input; my @target_choice = split("", $input); if ($input !~ /^[A-J]\d0?$/i) { print "You've entered invalid target. Please try again.\n"; &game_play::reg_mode::user_shot(); return 0; } $countshots++; print " shot count=", $countshots, " ", "\n"; foreach my $el (@target_choice) { my ($let) = split('', $el); ## ss edit my ($one) = split('', $el); ## ss edit my ($two) = split('', $el); ## ss edit if ($el eq "A") { $let = 0; ### ss edit } if ($el eq "B") { $let = 1; ### ss edit } if ($el eq "C") { $let = 2; ### ss edit } if ($el eq "D") { $let = 3; ### ss edit } if ($el eq "E") { $let = 4; ### ss edit } if ($el eq "F") { $let = 5; ### ss edit } if ($el eq "G") { $let = 6; ### ss edit } if ($el eq "H") { $let = 7; ### ss edit } if ($el eq "I") { $let = 8; ### ss edit } if ($el eq "J") { $let = 9; ### ss edit } my $num = 0; if ($two ne "") { $num = "$one" . "$two"; $num = $num - 1; } else { $num = $one - 1; } $input = "$let" . "$num"; print $el, "el again", "\n"; } ### ss warning foreach my $lee (@main::game_play::user_shots_check) { if ($choosen eq $lee) { print "You have entered invalid shot check. Please try again.\n" +; &game_play::reg_mode::user_shot(); return; } } foreach my $lee (@main::com_ships::com_all_ships) { if ($choosen eq $lee) { print "Computer ship hit!\n"; $main::com_ships::com_board[$let][$num] = 'X'; $main::com_ships::hits++; $countshots++; print $main::com_ships::hits, " press enter to continue", "\n"; $pausetillenter = <STDIN>; last; } elsif ($choosen ne $lee) { $main::com_ships::com_board[$let][$num] = 'O'; } } push @main::game_play::user_shots_check, $el; } sub game_play::dead_yet () { if ($main::com_ships::hits eq '6') { &game_play::end_game(2); } if ($main::user_ships::hits eq '6') { &game_play::end_game(1); } } sub game_play::end_game () { my @winner = @_; if ($winner[0] == 2) { print "Congratulations! You won, $main::startup::name!\n\n"; exit; } else { print "Computer hit all 6 objects ", $main::startup::name, " Shots +used=", $countshots, "\n"; exit; } } sub game_play::THE_END () { print "\n"; }
Re: ASCII Battleship Program
by oko1 (Deacon) on Feb 14, 2012 at 17:08 UTC

    Download, check - the tweaked version from roboticus, actually. Play, check (after fixing the two variables reported by '-w'.) Feel all old-school, check. :) Very cool for a first effort, indeed!

    In addition to the one-off positioning problem reported, the collision detector doesn't work during placement; I was able to place all my ships one on top of another (I think I heard the computer sobbing in frustration after shooting up half the board without a single hit.)

    From the coding end... yeah, gotta say: it's a mess. :) If I had to maintain such a thing, I would *much* rather have had it handed to me without any namespace declaration - all globals - than something like this.

    Also, it seems that somewhere along the way, you were taught that Thou Shalt Use Subroutines No Matter What. Actually, subroutines are used for specific reasons: modularization, for example, is a good one, and useful for creating short, easily readable "main" blocks, and for having "user functions" that you can call multiple times. But your main block isn't a readable, obvious description of program flow - it's just a series of calls to blocks of code, with no visible structure to it. To figure out what is happening in your program, you need to dive into the code itself... which sorta blows the whole idea out of the water. (Ahem. Pardon the metaphor, but I'm a sailor with 25 years of experience behind me, so I have certain privileges.)

    Another reasonable use for subroutines (I was going to say "subs"...) might be for keeping a sort of a small, private "working area" - that is, making it easy for yourself to see the entire scope of what you're working on, and creating a series of "black boxes" that take input, return output, and don't collide with each other because their content is effectively isolated (I know, I'm starting to preach OO here...) Not what's happening here, though.

    Please note that the above isn't really related to Perl specifically - it would apply no matter what language you were using. The problem I'm talking about isn't related so much to the functioning of the program as to the way that you "communicate" with your fellow programmers - anyone who comes along to read or maintain your code - which is what so much of the various programming patterns, etc. are all about. Yep, there are better ways of approaching the problems you're trying to solve - but they're not complex ones, and improving that is a different matter entirely. But when you write a program, please remember that you're not *just* solving those problems - you're also "writing to an audience", and _that_ communication needs to be as clear and explicit as possible.

    [ Oh, dear. I think I accidentally hit my 'rant' button. <click> OK, it's off now; everybody's safe. Whew. :) ]

    No matter what, though - thanks for the fun experience!!! It's definitely been a Blast From The Past.

    -- 
    I hate storms, but calms undermine my spirits.
     -- Bernard Moitessier, "The Long Way"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://951741]
Approved by toolic
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2024-04-18 17:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found