June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
99
Task/Tic-tac-toe/Fortran/tic-tac-toe.f
Normal file
99
Task/Tic-tac-toe/Fortran/tic-tac-toe.f
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
! This is a fortran95 implementation of the game of tic-tac-toe.
|
||||
! - Objective was to use less than 100 lines.
|
||||
! - No attention has been devoted to efficiency.
|
||||
! - Indentation by findent: https://sourceforge.net/projects/findent/
|
||||
! - This is free software, use as you like at own risk.
|
||||
! - Compile: gfortran -o tictactoe tictactoe.f90
|
||||
! - Run: ./tictactoe
|
||||
! Comments to: wvermin at gmail dot com
|
||||
module tic
|
||||
implicit none
|
||||
integer :: b(9)
|
||||
contains
|
||||
logical function iswin(p)
|
||||
integer,intent(in) :: p
|
||||
iswin = &
|
||||
all(b([1,2,3])==p).or.all(b([4,5,6])==p).or.all(b([7,8,9])==p).or.&
|
||||
all(b([1,4,7])==p).or.all(b([2,5,8])==p).or.all(b([3,6,9])==p).or.&
|
||||
all(b([1,5,9])==p).or.all(b([3,5,7])==p)
|
||||
end function iswin
|
||||
subroutine printb(mes)
|
||||
character(len=*) :: mes
|
||||
integer :: i,j
|
||||
character :: s(0:2) = ['.','X','O']
|
||||
print "(3a3,' ',3i3)",(s(b(3*i+1:3*i+3)),(j,j=3*i+1,3*i+3),i=0,2)
|
||||
if(mes /= ' ') print "(/,a)",mes
|
||||
end subroutine printb
|
||||
integer recursive function minmax(player,bestm) result(bestv)
|
||||
integer :: player,bestm,move,v,bm,win=1000,inf=100000
|
||||
real :: x
|
||||
if (all(b .ne. 0)) then
|
||||
bestv = 0
|
||||
else
|
||||
bestv = -inf
|
||||
do move=1,9
|
||||
if (b(move) == 0) then
|
||||
b(move) = player
|
||||
if (iswin(player)) then
|
||||
v = win
|
||||
else
|
||||
call random_number(x)
|
||||
v = -minmax(3-player,bm) - int(10*x)
|
||||
endif
|
||||
if (v > bestv) then
|
||||
bestv = v
|
||||
bestm = move
|
||||
endif
|
||||
b(move) = 0
|
||||
if (v == win) exit
|
||||
endif
|
||||
enddo
|
||||
endif
|
||||
end function minmax
|
||||
end module tic
|
||||
program tictactoe
|
||||
! computer: player=1, user: player=2
|
||||
use tic
|
||||
implicit none
|
||||
integer :: move,ios,v,bestmove,ply,player=2,k,values(8)
|
||||
integer,allocatable :: seed(:)
|
||||
call date_and_time(values=values)
|
||||
call random_seed(size=k)
|
||||
allocate(seed(k))
|
||||
seed = values(8)+1000*values(7)+60*1000*values(6)+60*60*1000*values(5)
|
||||
call random_seed(put=seed)
|
||||
mainloop: do
|
||||
b = 0
|
||||
call printb('You have O, I have X. You enter 0: game ends.')
|
||||
plyloop: do ply=0,4
|
||||
if (player == 2 .or. ply >0 ) then ! user move
|
||||
write(*,"(/,a)",advance='no'),'Your move? (0..9) '
|
||||
getloop: do
|
||||
readloop: do
|
||||
read (*,*,iostat=ios),move
|
||||
if (ios == 0 .and. move >= 0 .and. move <= 9) exit readloop
|
||||
write(*,"(a)",advance='no'),'huh? Try again (0..9): '
|
||||
enddo readloop
|
||||
if ( move == 0) exit mainloop
|
||||
if (b(move) == 0) exit getloop
|
||||
write(*,"(a)",advance='no'),'Already occupied, again (0..9): '
|
||||
enddo getloop
|
||||
b(move) = 2
|
||||
if(iswin(2)) then ! this should not happen
|
||||
call printb('***** You win *****')
|
||||
exit plyloop
|
||||
endif
|
||||
endif
|
||||
v = minmax(1,bestmove) ! computer move
|
||||
b(bestmove) = 1
|
||||
if(iswin(1)) then
|
||||
call printb('***** I win *****')
|
||||
exit plyloop
|
||||
endif
|
||||
write(*,"(/,a,i3)"), 'My move: ',bestmove
|
||||
call printb(' ')
|
||||
enddo plyloop
|
||||
if(ply == 5) write(*,"('***** Draw *****',/)")
|
||||
player = 3-player
|
||||
enddo mainloop
|
||||
end program
|
||||
Loading…
Add table
Add a link
Reference in a new issue