Home > Archive > Fortran > December 2006 > herding global vars to a module
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
herding global vars to a module
|
|
| lane straatman 2006-12-15, 7:06 pm |
| program poker5
IMPLICIT NONE
integer, dimension(52) :: cards
call random_seed()
call shuffle(cards)
call deal(cards)
WRITE(*,*) cards
contains
subroutine shuffle(cards)
integer :: cards(:), ii, index
real :: numbers(size(cards))
call random_number(numbers)
do ii = 1, size(cards)
index = minloc(numbers, dim=1)
cards(ii) = index
numbers(index) = 2.0
end do
end subroutine shuffle
subroutine deal(cards)
integer :: cards(:), players, j ,i, hold
character(len=20), dimension(52) :: a
a(1)='Two of clubs'
a(2)='Three of clubs'
a(3)='Four of clubs'
a(4)='Five of clubs'
a(5)='Six of clubs'
a(6)='Seven of clubs'
a(7)='Eight of clubs'
a(8)='Nine of clubs'
a(9)='Ten of clubs'
a(10)='Jack of clubs'
a(11)='Queen of clubs'
a(12)='King of clubs'
a(13)='Ace of clubs'
a(14)='Two of diamonds'
a(15)='Three of diamonds'
a(16)='Four of diamonds'
a(17)='Five of diamonds'
a(18)='Six of diamonds'
a(19)='Seven of diamonds'
a(20)='Eight of diamonds'
a(21)='Nine of diamonds'
a(22)='Ten of diamonds'
a(23)='Jack of diamonds'
a(24)='Queen of diamonds'
a(25)='King of diamonds'
a(26)='Ace of diamonds'
a(27)='Two of hearts'
a(28)='Three of hearts'
a(29)='Four of hearts'
a(30)='Five of hearts'
a(31)='Six of hearts'
a(32)='Seven of hearts'
a(33)='Eight of hearts'
a(34)='Nine of hearts'
a(35)='Ten of hearts'
a(36)='Jack of hearts'
a(37)='Queen of hearts'
a(38)='King of hearts'
a(39)='Ace of hearts'
a(40)='Two of spades'
a(41)='Three of spades'
a(42)='Four of spades'
a(43)='Five of spades'
a(44)='Six of spades'
a(45)='Seven of spades'
a(46)='Eight of spades'
a(47)='Nine of spades'
a(48)='Ten of spades'
a(49)='Jack of spades'
a(50)='Queen of spades'
a(51)='King of spades'
a(52)='Ace of spades'
players = 10
hold = 2*players
do i = 1, hold , 2
do j = 0 , 1
write(*,'(i5, a)',ADVANCE='NO') (i+j), a(cards(i+j))
end do
write(6,'(A)',ADVANCE='YES')
end do
write(*,'(a,a,a,a)') "flop: ", a(cards(hold+1)), a(cards(hold+2)),
a(cards(hold+3))
write(*,'(a,a)') "turn: ", a(cards(hold+4))
write(*,'(a,a)')"river: ", a(cards(hold+5))
end subroutine deal
end program
The purpose of this longish post is to get the enumerated char array
a() out of the sight without being out of scope. I believe that the
best way to do this with data that are considered "global" is to herd
them into a module. If I put the 'uses' statement after declaring the
program, would it always stay in scope? Alternatively, I would think
that I would need a 'uses' in any subroutine where I want to know what
the cards are.
a() is an unfortunate choice of array name with the write specifier to
confuse it with. I was thinking that for the figuring I would make a
struct:
type foo
integer :: index, cardno
character(len=20) :: name
character(len=1) :: suit
end type foo
The queen of spades would have index 50, cardno 11, 'Queen of spades',
'S' . How does a person construct this properly? In the examples in
MRC with a struct being contructed, only one field is shown, which is
basically the above (/ and /) as bookends. LS
| |
| Michael Metcalf 2006-12-15, 7:06 pm |
|
"lane straatman" <grumpy196884@netzero.net> wrote in message
news:1166225061.381977.224520@79g2000cws.googlegroups.com...
> The purpose of this longish post is to get the enumerated char array
> a() out of the sight without being out of scope. I believe that the
> best way to do this with data that are considered "global" is to herd
> them into a module. If I put the 'uses' statement after declaring the
> program, would it always stay in scope? Alternatively, I would think
> that I would need a 'uses' in any subroutine where I want to know what
> the cards are.
You can put you cards' definitions in a module. You then USE it in the main
program, so that it's in scope for the whole program (MR&C, Sectionn 7.9),
and in any subprogram that requires it. You can give them the parameter
attribute too:
character(len=20), dimension(52), parameter :: a = (/
&
'Two of clubs ','Three of clubs ','Four of clubs ','Five of clubs
', &
'Six of clubs ','Seven of clubs ','Eight of clubs ','Nine of clubs
', &
'Ten of clubs ','Jack of clubs ','Queen of clubs ','King of clubs
', &
'Ace of clubs ',
&
'Two of diamonds ','Three of diamonds','Four of diamonds ','Five of
diamonds ', &
'Six of diamonds ','Seven of diamonds','Eight of diamonds','Nine of
diamonds ', &
'Ten of diamonds ','Jack of diamonds ','Queen of diamonds','King of
diamonds ', &
'Ace of diamonds ',
&
'Two of hearts ','Three of hearts ','Four of hearts ','Five of hearts
', &
'Six of hearts ','Seven of hearts ','Eight of hearts ','Nine of hearts
', &
'Ten of hearts ','Jack of hearts ','Queen of hearts ','King of hearts
', &
'Ace of hearts ',
&
'Two of spades ','Three of spades ','Four of spades ','Five of spades
', &
'Six of spades ','Seven of spades ','Eight of spades ','Nine of spades
', &
'Ten of spades ','Jack of spades ','Queen of spades ','King of spades
', &
'Ace of spades ' /)
>
> a() is an unfortunate choice of array name with the write specifier to
> confuse it with. I was thinking that for the figuring I would make a
> struct:
> type foo
> integer :: index, cardno
> character(len=20) :: name
> character(len=1) :: suit
> end type foo
> The queen of spades would have index 50, cardno 11, 'Queen of spades',
> 'S' . How does a person construct this properly? In the examples in
> MRC with a struct being contructed, only one field is shown, which is
> basically the above (/ and /) as bookends. LS
>
Is this roughly what you want:
module m
type foo
integer :: index, cardno
character(len=20) :: name
character(len=1) :: suit
end type foo
end module m
program poker5
use m
type(foo), parameter :: cards(2) = (/ foo(1,2,'Two of clubs' ,'c' ), &
foo(2,3,'Three of clubs ', 'c') /)
print *, cards
end program
?
HTH,
Mike Metcalf
| |
| lane straatman 2006-12-16, 7:07 pm |
|
[MM:]
> Is this roughly what you want:
>
> module m
> type foo
> integer :: index, cardno
> character(len=20) :: name
> character(len=1) :: suit
> end type foo
> end module m
> program poker5
> use m
> type(foo), parameter :: cards(2) = (/ foo(1,2,'Two of clubs' ,'c' ), &
> foo(2,3,'Three of clubs ', 'c') /)
> print *, cards
> end program
Thanks for your reply. I decided to use fortran to make the deck's
attributes. What follows is an abridged version of output of program
makedeck, as it is redirected to a text file. (With windows, use the
dos prompt to get to the directory in which makedeck.exe lives and
enter makedeck >text.txt )
(/ &
foo( 1, 1,Two of clubs ,'c'),&
| |
| Terence 2006-12-16, 10:05 pm |
| I prefer to read into array CARDNO a message file with the definitions
of the text for the indices 1..52.
Then you can use ANY byte-based language, even Romanji (and more
recently in my case, and surprise, upper-table modern Gr ). Ton
kratounta malthakos...
In the same way the rules of the game you are playing come into the
text holders you have supplied. I have a general purpose routine for
this which I call on entry to any and every program; then the user can
switch languages with one key-stroke.
| |
| Michael Metcalf 2006-12-16, 10:05 pm |
|
"lane straatman" <grumpy196884@netzero.net> wrote in message
news:1166300624.625835.263830@j72g2000cwa.googlegroups.com...
> This would yield
> module m
> [ struct that looks a lot like it was pasted from makedeck]
> end module m
> In main, would I just write
> use m <- NOT uses
> or do I have to re-declare?
>
No. Please consult any textbook for further examples.
Regards,
Mike Metcalf
| |
| Brooks Moses 2006-12-17, 4:12 am |
| lane straatman wrote:
> a() is an unfortunate choice of array name with the write specifier to
> confuse it with. I was thinking that for the figuring I would make a
> struct:
> type foo
> integer :: index, cardno
> character(len=20) :: name
> character(len=1) :: suit
> end type foo
> The queen of spades would have index 50, cardno 11, 'Queen of spades',
> 'S' . How does a person construct this properly? In the examples in
> MRC with a struct being contructed, only one field is shown, which is
> basically the above (/ and /) as bookends. LS
Really, I'd suggest not doing it that way at all, but using something
like this, which is rather shorter:
module cards
character(len=8), parameter :: suitnames(4) = &
(/ 'clubs ', 'hearts ', 'spades ', 'diamonds' /)
character(len=), parameter :: cardnames(13) = &
(/ 'Ace ', 'Two ', 'Three', 'Four ', 'Five ' &
'Six ', 'Seven', 'Eight', 'Nine ', 'Ten ' &
'Jack ', 'Queen', 'King ' /)
contains
function cardname(suit, number) result(name)
integer, intent(in) :: suit, number
character(len=20) :: name
name = trim(cardnames(number)) // ' of ' // &
trim(suitnames(suit))
end function
end module
If you then then want to initialize an array of 52 "card" structures,
you can initialize them at runtime based on this in a simple loop, and
the overall code is _still_ shorter and easier to read than the long
list of initializers.
For a deck of cards, the time to initialize it at runtime is completely
trivial. For something large enough for the time delay to matter, it's
entirely possible that calculating it is faster than reading the values
off the disk when the program is loaded, and so I'd recommending testing
rather than assuming that a pre-initialized version is faster (unless
it's obviously expensive to compute).
- Brooks
--
The "bmoses-nospam" address is valid; no unmunging needed.
| |
| lane straatman 2006-12-18, 7:08 pm |
|
Brooks Moses wrote:
> lane straatman wrote:
>
> Really, I'd suggest not doing it that way at all, but using something
> like this, which is rather shorter:
>
> module cards
> character(len=8), parameter :: suitnames(4) = &
> (/ 'clubs ', 'hearts ', 'spades ', 'diamonds' /)
> character(len=), parameter :: cardnames(13) = &
> (/ 'Ace ', 'Two ', 'Three', 'Four ', 'Five ' &
> 'Six ', 'Seven', 'Eight', 'Nine ', 'Ten ' &
> 'Jack ', 'Queen', 'King ' /)
> contains
> function cardname(suit, number) result(name)
> integer, intent(in) :: suit, number
> character(len=20) :: name
> name = trim(cardnames(number)) // ' of ' // &
> trim(suitnames(suit))
> end function
> end module
>
> If you then then want to initialize an array of 52 "card" structures,
> you can initialize them at runtime based on this in a simple loop, and
> the overall code is _still_ shorter and easier to read than the long
> list of initializers.
>
> For a deck of cards, the time to initialize it at runtime is completely
> trivial. For something large enough for the time delay to matter, it's
> entirely possible that calculating it is faster than reading the values
> off the disk when the program is loaded, and so I'd recommending testing
> rather than assuming that a pre-initialized version is faster (unless
> it's obviously expensive to compute).
Thanks all for replies. I'll fire up Brooks' source when I get home.
It certainly looks more elegant than brute force. At least half of the
problem is that I'm new to the syntax, so "better" solutions may not
work if only for the reason that I don't get it. Some things a person
can pick up on the fly, such as his concatenation with trim and //. I
can't follow execution of the entire snippet at this point; indeed I
can't see what type my cards are going to be. LS
|
|
|
|
|