File: create_units.pl

package info (click to toggle)
ogamesim 20130107-3
  • links: PTS
  • area: main
  • in suites: buster
  • size: 804 kB
  • ctags: 214
  • sloc: ansic: 1,621; perl: 1,041; makefile: 201
file content (208 lines) | stat: -rw-r--r-- 4,884 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/usr/bin/perl

use warnings;
use strict;

#====================================================================
# собственно сам генератор файлов
#====================================================================
use Getopt::Long;
select STDERR; $|=1; select STDOUT;

my ($output_file, $header_file, $input_file);

sub usage()
{
  print <<eof;
  Usage $0 input_file [ -c output_file.c ] [ -h output_file.h ]
eof
  exit -1;
}


GetOptions(
  "c=s"       =>  \$output_file,
  "h=s"       =>  \$header_file,
)  or usage;

$input_file=shift @ARGV or usage;

# если указан выходной файл то делаем его
# вместо stdout
if ($output_file)
{
  open OUTPUT, ">", $output_file 
    or die "Can not open '$output_file': $!";
  select OUTPUT;
}


# читаем конфиг-файл
open my $config, "<", $input_file 
  or die "Can not open '$input_file': $!";
my @lines=grep /^\s*unit\d/, <$config>;
close $config;

s/\s+$//, s/^\s+//, s/#.*$// for @lines;

my @units;

# сюда складываем некоторые defines'ы для h-файла
my @defines; 

for (my $uno=1; my @ulines=grep /^unit$uno\./, @lines; $uno++)
{
  my %unit;

  for my $field (qw(name order structure 
      shield attack capacity ground metal crystal deut
      large_chargo small_chargo recycler))
  {
    ($unit{$field})=grep /^unit$uno\.$field/, @ulines 
      and $unit{$field}=~s/^.*?=\s*//;
    defined $unit{$field} or $unit{$field}=0;
  }

  unless ($unit{metal}+$unit{crystal}==$unit{structure}) 
  {
    print STDERR "'$unit{name}': error defined cost parameters\n",
      "\tmetal=$unit{metal}\n\tcrystal=$unit{crystal}\n\t",
      "deuterium=$unit{deut}\n\tstructere=$unit{structure}\n";
    exit 10;
  }

  my @rapid;

  for (my $rno=1; my @rlines=grep /^unit$uno\.rapid$rno\./, @ulines; $rno++)
  {
    my ($rapin_unit)=grep /unit$uno\.rapid$rno\.name/, @rlines;
    my ($rapin_value)=grep /unit$uno\.rapid$rno\.value/, @rlines;
    $rapin_unit=~s/^.*?=\s*//; $rapin_value=~s/^.*?=\s*//;
    push @rapid, [ $rapin_unit => $rapin_value ];
  }

  $unit{rapids}=\@rapid if @rapid;
  push @units, \%unit;
}
@units=sort { $a->{order} <=> $b->{order} } @units;

print <<eof;
/* 
  Этот файл сгенерирован при помощи утилиты '$0'
  поэтому менять его руками не стоит.
  При генерации данные взяты из файла '$input_file'

*/
eof
print qq(#include "unit.h"\n\n);
print "/* Oбщее описание юнитов */\n";
print "unit_info units[]=\n{\n";
my ($rno, $maxrapids)=(1,0);

my $uno=0;
for (@units)
{
  print "  {\n    \"$_->{name}\" /* name */,\n";


  for my $field(qw(shield structure attack capacity metal crystal deut))
  {
    printf "    %-8d /* %s */,\n", $_->{$field}, $field;
  }
  
  print "    {\n";
  for my $field (qw(ground large_chargo small_chargo recycler))
  {
    printf "      %-6d /* %s */,\n", $_->{$field}, $field;

    if ($field ne 'ground' and $_->{$field})
    {
      my $name=$field;
      $name=~tr/a-z/A-Z/;
      push @defines, "#define $name $uno";
    }
  }
  print "    },\n";
  
  if ($_->{rapids})
  {
    printf "    %-8d /* rapidno */\n", $rno;
    $rno++;
    $maxrapids=scalar @{$_->{rapids}} 
      if $maxrapids < scalar @{$_->{rapids}};
  }
  else 
  {
    printf "    %-8d /* rapidno */\n", 0;
  }
  print "  },\n";
  $uno++;
}
print "};\n\n";

my $units_count=scalar @units;
$maxrapids++;
print "/* Скорострелы */\n";
print "rapidfire rapids[$rno][$maxrapids]=\n{\n";

print "  { { 0, 0, 0 }, },\n";
for my $unit (@units)
{
  defined $unit->{rapids} or next;
  print "\n  /* $unit->{name} */\n  {\n";
  
  for (@{$unit->{rapids}})
  {
    my ($uname, $rapid)=@{$_};
    my $uid=0;
    
    # определяем ID юнита против которого скорострел
    for ($uid=0; $uid<scalar @units; $uid++)
    {
      $uname eq $units[$uid]->{name} and last;
    }

    my $chance=0;

    # шанс = (1/e) в степени 1/скорострел
    $rapid and $chance=1-(1/$rapid);

    printf "    { %2d, %5d, $chance },\n", $uid, $rapid;
  }
  print "  },\n";
}
print "};\n";


select STDOUT;
if ($header_file)
{
  open HEADER, ">", $header_file
    or die "Can not open '$header_file': $!";
  select HEADER;
}

my $defines=join "\n", @defines;

print <<eof;
#ifndef __UNITS__INFO__H__
#define __UNITS__INFO__H__

#include "unit.h"
/*
  Этот файл сгенерирован при помощи утилиты '$0'
  поэтому менять его руками не стоит.
  При генерации данные взяты из файла '$input_file'
*/

#define UNITS_COUNT   $units_count
#define RAPIDS_COUNT  ($maxrapids-1)

$defines

extern unit_info units[$units_count];
extern rapidfire rapids[$rno][$maxrapids];

#endif
eof