view release on metacpan or search on metacpan
# This file was automatically generated by Dist::Zilla::Plugin::ModuleBuild v6.024.
use strict;
use warnings;
use Module::Build 0.28;
my %module_build_args = (
"build_requires" => {
"Module::Build" => "0.28"
},
"configure_requires" => {
"Module::Build" => "0.28"
},
"dist_abstract" => "optimize path finding searches for a large set of initial conditions (for better average performance).",
"dist_author" => [
"Shlomi Fish <shlomif\@cpan.org>"
],
"dist_name" => "AI-Pathfinding-OptimizeMultiple",
"dist_version" => "0.0.17",
"license" => "mit",
"module_name" => "AI::Pathfinding::OptimizeMultiple",
"recursive_test_files" => 1,
"requires" => {
"Carp" => 0,
"Exception::Class" => 0,
"File::Path" => 0,
"Getopt::Long" => 0,
"IO::File" => 0,
"MooX" => 0,
"MooX::Types::MooseLike::Base" => 0,
"MooX::late" => "0.007",
"PDL" => 0,
"PDL::IO::FastRaw" => 0,
"Scalar::Util" => 0,
"autodie" => 0,
"perl" => "5.012",
"strict" => 0,
"vars" => 0,
"warnings" => 0
},
"script_files" => [
"bin/optimize-game-ai-multi-tasking"
],
"test_requires" => {
"File::Spec" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
"Test::Differences" => 0,
"Test::More" => "0.88"
}
);
my %fallback_build_requires = (
"File::Spec" => 0,
"IO::Handle" => 0,
"IPC::Open3" => 0,
"Module::Build" => "0.28",
"Test::Differences" => 0,
"Test::More" => "0.88"
);
unless ( eval { Module::Build->VERSION(0.4004) } ) {
delete $module_build_args{test_requires};
$module_build_args{build_requires} = \%fallback_build_requires;
}
my $build = Module::Build->new(%module_build_args);
$build->create_build_script;
0.0.17 2022-10-27
- Fix tests with latest PDL.
- https://rt.cpan.org/Ticket/Display.html?id=144651
- Thanks to SREZIC
0.0.16 2020-10-20
- dist.ini / weaver.ini / .tidyallrc / etc. cleanup
- Move to @SHLOMIF
- Inspired by Lady_Aleena.
v0.0.15 2017-05-01
- Skip adding ~$ files to the MANIFEST.
- See https://rt.cpan.org/Ticket/Display.html?id=121485 .
- Thanks to Toby Inkster.
v0.0.14 2017-05-01
- Convert dist.ini to use the @SHLOMIF bundle.
- Fix a bug where a pdl was passed instead of an int.
- See https://rt.cpan.org/Ticket/Display.html?id=121478
- Thanks to Slaven Rezic and Toby Inkster.
v0.0.13 2016-04-20
- Improve the exception handling due to a non-Exception::Class error:
- http://www.cpantesters.org/cpan/report/f631b3e2-03b5-11e6-b1a3-5205ef11d1c8
- Thanks also to the example code in
https://metacpan.org/pod/Exception::Class .
- Add Test::Kwalitee::Extra.
v0.0.12 2015-03-26
- Add the stats_factors option to the
lib/AI/Pathfinding/OptimizeMultiple.pm constructor.
- Contains some factors to normalise the iters of specific scans.
- Add the --stats-factors option to ::CmdLine.
- Allow to customise the --total-iterations-limit using
$ENV{FC_SOLVE_RANGE_ITERS_LIMIT} .
v0.0.11 2014-03-29
- Move the external-deps-using release tests to xt/ instead of t/
- Better Kwalitee.
- Thanks to "ether" on #distzilla for the insights on fixing it.
v0.0.10 2014-03-28
- Convert to the Test::CPAN::Changes Dist-Zilla plugin.
v0.0.9 2014-03-28
- Add an explicit symbol import on "use PDL"/etc.
- Add get_scan_ids_aref() and lookup_scan_idx_based_on_id() to
AI::Pathfinding::OptimizeMultiple::DataInputObj .
- Add the $args parameter with the 'chosen_scans' key to
AI::Pathfinding::OptimizeMultiple::simulate_board() .
- Add support for some extra required options in
AI::Pathfinding::OptimizeMultiple::DataInputObjâs time-scan.pl.
v0.0.8 2014-02-02
- Made sure the =encoding directive is on top of the file in
bin/optimize-game-ai-multi-tasking .
v0.0.7 2014-01-26
- Minimal version of perl - 5.012 in the prereqs (could be lower, possibly).
- For Kwalitee.
- Remove the Makefile.PL so we will have "metayml has provides".
- Now it's Build.PL-only.
- Add provides to the META.yml.
v0.0.6 2014-01-25
- Add "use strict;" and "use warnings;" to MooX::late modules.
- Kwalitee
- Remove the ^Rejects and ^scripts sub-directories.
- They were confusing CPANTS and reduced our Kwalitee.
v0.0.5 2013-01-22
- skipping compile test for scripts/bump-version-number.pl .
- it is for use by the module's maintainer and has
non-essential prereqs.
v0.0.4 2013-01-20
- Add missing Prerequisites
- MooX::late
- MooX::Types::MooseLike::Base
v0.0.3 2013-01-18
- Fixed broken POD for hyperlinks.
v0.0.2 2013-01-17
- Fixed the POD - removed extraneous sections and added a NAME handler.
- Part of it was caused due to a Pod::Weaver misconfiguration
v0.0.1 2013-01-17
- First version, released on an unsuspecting world.
- Everything is still subject to change and break.
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
The MIT License
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to
whom the Software is furnished to do so, subject to the
{
"abstract" : "optimize path finding searches for a large set of initial conditions (for better average performance).",
"author" : [
"Shlomi Fish <shlomif@cpan.org>"
],
"dynamic_config" : 0,
"generated_by" : "Dist::Zilla version 6.024, CPAN::Meta::Converter version 2.150010",
"license" : [
"mit"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : 2
},
"name" : "AI-Pathfinding-OptimizeMultiple",
"prereqs" : {
"build" : {
"requires" : {
"Module::Build" : "0.28"
}
},
"configure" : {
"requires" : {
"Module::Build" : "0.28"
}
},
"develop" : {
"requires" : {
"Pod::Coverage::TrustPod" : "0",
"Test::CPAN::Changes" : "0.19",
"Test::EOL" : "0",
"Test::More" : "0.96",
"Test::NoTabs" : "0",
"Test::Pod" : "1.41",
"Test::Pod::Coverage" : "1.08",
"Test::TrailingSpace" : "0.0203"
}
},
"runtime" : {
"requires" : {
"Carp" : "0",
"Exception::Class" : "0",
"File::Path" : "0",
"Getopt::Long" : "0",
"IO::File" : "0",
"MooX" : "0",
"MooX::Types::MooseLike::Base" : "0",
"MooX::late" : "0.007",
"PDL" : "0",
"PDL::IO::FastRaw" : "0",
"Scalar::Util" : "0",
"autodie" : "0",
"perl" : "5.012",
"strict" : "0",
"vars" : "0",
"warnings" : "0"
}
},
"test" : {
"requires" : {
"File::Spec" : "0",
"IO::Handle" : "0",
"IPC::Open3" : "0",
"Test::Differences" : "0",
"Test::More" : "0.88"
}
}
},
"provides" : {
"AI::Pathfinding::OptimizeMultiple" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::App::CmdLine" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::DataInputObj" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/DataInputObj.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::IterState" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/IterState.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::PostProcessor" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/PostProcessor.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::Scan" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/Scan.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::ScanRun" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm",
"version" : "v0.0.17"
},
"AI::Pathfinding::OptimizeMultiple::SimulationResults" : {
"file" : "lib/AI/Pathfinding/OptimizeMultiple/SimulationResults.pm",
"version" : "v0.0.17"
}
},
"release_status" : "stable",
"resources" : {
"bugtracker" : {
"web" : "https://github.com/shlomif/fc-solve/issues"
},
"homepage" : "http://metacpan.org/release/AI-Pathfinding-OptimizeMultiple",
"repository" : {
"type" : "git",
"url" : "ssh://git@github.com/shlomif/fc-solve.git",
"web" : "http://github.com/shlomif/fc-solve"
}
},
"version" : "0.0.17",
"x_Dist_Zilla" : {
"perl" : {
"version" : "5.034001"
},
"plugins" : [
{
"class" : "Dist::Zilla::Plugin::Prereqs",
"config" : {
"Dist::Zilla::Plugin::Prereqs" : {
"phase" : "test",
"type" : "requires"
}
},
"name" : "@Filter/TestMoreDoneTesting",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::AutoPrereqs",
"name" : "@Filter/AutoPrereqs",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::ExecDir",
"name" : "@Filter/ExecDir",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::GatherDir",
"config" : {
"Dist::Zilla::Plugin::GatherDir" : {
"exclude_filename" : [],
"exclude_match" : [],
"follow_symlinks" : 0,
"include_dotfiles" : 0,
"prefix" : "",
"prune_directory" : [],
"root" : "."
}
},
"name" : "@Filter/GatherDir",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::License",
"name" : "@Filter/License",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::ManifestSkip",
"name" : "@Filter/ManifestSkip",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::MetaYAML",
"name" : "@Filter/MetaYAML",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PruneCruft",
"name" : "@Filter/PruneCruft",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::Readme",
"name" : "@Filter/Readme",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::RunExtraTests",
"config" : {
"Dist::Zilla::Role::TestRunner" : {
"default_jobs" : "4"
}
},
"name" : "@Filter/RunExtraTests",
"version" : "0.029"
},
{
"class" : "Dist::Zilla::Plugin::ShareDir",
"name" : "@Filter/ShareDir",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::CheckChangesHasContent",
"name" : "@Filter/CheckChangesHasContent",
"version" : "0.011"
},
{
"class" : "Dist::Zilla::Plugin::ConfirmRelease",
"name" : "@Filter/ConfirmRelease",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::Manifest",
"name" : "@Filter/Manifest",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::MetaConfig",
"name" : "@Filter/MetaConfig",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::MetaJSON",
"name" : "@Filter/MetaJSON",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::MetaProvides::Package",
"config" : {
"Dist::Zilla::Plugin::MetaProvides::Package" : {
"finder_objects" : [
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : "@Filter/MetaProvides::Package/AUTOVIV/:InstallModulesPM",
"version" : "6.024"
}
],
"include_underscores" : 0
},
"Dist::Zilla::Role::MetaProvider::Provider" : {
"$Dist::Zilla::Role::MetaProvider::Provider::VERSION" : "2.002004",
"inherit_missing" : 1,
"inherit_version" : 1,
"meta_noindex" : 1
},
"Dist::Zilla::Role::ModuleMetadata" : {
"Module::Metadata" : "1.000037",
"version" : "0.006"
}
},
"name" : "@Filter/MetaProvides::Package",
"version" : "2.004003"
},
{
"class" : "Dist::Zilla::Plugin::MetaResources",
"name" : "@Filter/MetaResources",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::ModuleBuild",
"config" : {
"Dist::Zilla::Role::TestRunner" : {
"default_jobs" : "4"
}
},
"name" : "@Filter/ModuleBuild",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PkgVersion",
"name" : "@Filter/PkgVersion",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PodCoverageTests",
"name" : "@Filter/PodCoverageTests",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PodSyntaxTests",
"name" : "@Filter/PodSyntaxTests",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::Test::Compile",
"config" : {
"Dist::Zilla::Plugin::Test::Compile" : {
"bail_out_on_fail" : 0,
"fail_on_warning" : "author",
"fake_home" : 0,
"filename" : "t/00-compile.t",
"module_finder" : [
":InstallModules"
],
"needs_display" : 0,
"phase" : "test",
"script_finder" : [
":PerlExecFiles"
],
"skips" : [],
"switch" : []
}
},
"name" : "@Filter/Test::Compile",
"version" : "2.058"
},
{
"class" : "Dist::Zilla::Plugin::Test::CPAN::Changes",
"config" : {
"Dist::Zilla::Plugin::Test::CPAN::Changes" : {
"changelog" : "Changes"
}
},
"name" : "@Filter/Test::CPAN::Changes",
"version" : "0.012"
},
{
"class" : "Dist::Zilla::Plugin::Test::EOL",
"config" : {
"Dist::Zilla::Plugin::Test::EOL" : {
"filename" : "xt/author/eol.t",
"finder" : [
":ExecFiles",
":InstallModules",
":TestFiles"
],
"trailing_whitespace" : 1
}
},
"name" : "@Filter/Test::EOL",
"version" : "0.19"
},
{
"class" : "Dist::Zilla::Plugin::Test::NoTabs",
"config" : {
"Dist::Zilla::Plugin::Test::NoTabs" : {
"filename" : "xt/author/no-tabs.t",
"finder" : [
":InstallModules",
":ExecFiles",
":TestFiles"
]
}
},
"name" : "@Filter/Test::NoTabs",
"version" : "0.15"
},
{
"class" : "Dist::Zilla::Plugin::Test::TrailingSpace",
"name" : "@Filter/Test::TrailingSpace",
"version" : null
},
{
"class" : "Dist::Zilla::Plugin::TestRelease",
"name" : "@Filter/TestRelease",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PodWeaver",
"config" : {
"Dist::Zilla::Plugin::PodWeaver" : {
"finder" : [
":InstallModules",
":ExecFiles"
],
"plugins" : [
{
"class" : "Pod::Weaver::Plugin::SingleEncoding",
"name" : "@SHLOMIF/SingleEncoding",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Plugin::WikiDoc",
"name" : "@SHLOMIF/WikiDoc",
"version" : "0.093004"
},
{
"class" : "Pod::Weaver::Plugin::EnsurePod5",
"name" : "@CorePrep/EnsurePod5",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Plugin::H1Nester",
"name" : "@CorePrep/H1Nester",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@SHLOMIF/Name",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Version",
"name" : "@SHLOMIF/Version",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Region",
"name" : "@SHLOMIF/Prelude",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@SHLOMIF/Synopsis",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@SHLOMIF/Description",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@SHLOMIF/Usage",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@SHLOMIF/Overview",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Generic",
"name" : "@SHLOMIF/Stability",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Requirements",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Attributes",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Constructors",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Methods",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Collect",
"name" : "Functions",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Leftovers",
"name" : "@SHLOMIF/Leftovers",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Region",
"name" : "@SHLOMIF/postlude",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Support",
"name" : "@SHLOMIF/Support",
"version" : "1.013"
},
{
"class" : "Pod::Weaver::Section::Authors",
"name" : "@SHLOMIF/Authors",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Bugs",
"name" : "@SHLOMIF/Bugs",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Section::Contributors",
"name" : "@SHLOMIF/Contributors",
"version" : "0.009"
},
{
"class" : "Pod::Weaver::Section::Legal",
"name" : "@SHLOMIF/Legal",
"version" : "4.018"
},
{
"class" : "Pod::Weaver::Plugin::Transformer",
"name" : "@SHLOMIF/List",
"version" : "4.018"
}
]
}
},
"name" : "@Filter/PodWeaver",
"version" : "4.009"
},
{
"class" : "Dist::Zilla::Plugin::UploadToCPAN",
"name" : "@Filter/UploadToCPAN",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::AutoPrereqs",
"name" : "AutoPrereqs",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::Prereqs",
"config" : {
"Dist::Zilla::Plugin::Prereqs" : {
"phase" : "runtime",
"type" : "requires"
}
},
"name" : "Prereqs",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PruneCruft",
"name" : "PruneCruft",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::PruneFiles",
"name" : "PruneFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::RunExtraTests",
"config" : {
"Dist::Zilla::Role::TestRunner" : {
"default_jobs" : "4"
}
},
"name" : "RunExtraTests",
"version" : "0.029"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":InstallModules",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":IncModules",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":TestFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":ExtraTestFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":ExecFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":PerlExecFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":ShareFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":MainModule",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":AllFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : ":NoFiles",
"version" : "6.024"
},
{
"class" : "Dist::Zilla::Plugin::FinderCode",
"name" : "@Filter/MetaProvides::Package/AUTOVIV/:InstallModulesPM",
"version" : "6.024"
}
],
"zilla" : {
"class" : "Dist::Zilla::Dist::Builder",
"config" : {
"is_trial" : 0
},
"version" : "6.024"
}
},
"x_generated_by_perl" : "v5.34.1",
"x_serialization_backend" : "Cpanel::JSON::XS version 4.26",
"x_spdx_expression" : "MIT"
}
---
abstract: 'optimize path finding searches for a large set of initial conditions (for better average performance).'
author:
- 'Shlomi Fish <shlomif@cpan.org>'
build_requires:
File::Spec: '0'
IO::Handle: '0'
IPC::Open3: '0'
Module::Build: '0.28'
Test::Differences: '0'
Test::More: '0.88'
configure_requires:
Module::Build: '0.28'
dynamic_config: 0
generated_by: 'Dist::Zilla version 6.024, CPAN::Meta::Converter version 2.150010'
license: mit
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: '1.4'
name: AI-Pathfinding-OptimizeMultiple
provides:
AI::Pathfinding::OptimizeMultiple:
file: lib/AI/Pathfinding/OptimizeMultiple.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::App::CmdLine:
file: lib/AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::DataInputObj:
file: lib/AI/Pathfinding/OptimizeMultiple/DataInputObj.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::IterState:
file: lib/AI/Pathfinding/OptimizeMultiple/IterState.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::PostProcessor:
file: lib/AI/Pathfinding/OptimizeMultiple/PostProcessor.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::Scan:
file: lib/AI/Pathfinding/OptimizeMultiple/Scan.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::ScanRun:
file: lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm
version: v0.0.17
AI::Pathfinding::OptimizeMultiple::SimulationResults:
file: lib/AI/Pathfinding/OptimizeMultiple/SimulationResults.pm
version: v0.0.17
requires:
Carp: '0'
Exception::Class: '0'
File::Path: '0'
Getopt::Long: '0'
IO::File: '0'
MooX: '0'
MooX::Types::MooseLike::Base: '0'
MooX::late: '0.007'
PDL: '0'
PDL::IO::FastRaw: '0'
Scalar::Util: '0'
autodie: '0'
perl: '5.012'
strict: '0'
vars: '0'
warnings: '0'
resources:
bugtracker: https://github.com/shlomif/fc-solve/issues
homepage: http://metacpan.org/release/AI-Pathfinding-OptimizeMultiple
repository: ssh://git@github.com/shlomif/fc-solve.git
version: 0.0.17
x_Dist_Zilla:
perl:
version: '5.034001'
plugins:
-
class: Dist::Zilla::Plugin::Prereqs
config:
Dist::Zilla::Plugin::Prereqs:
phase: test
type: requires
name: '@Filter/TestMoreDoneTesting'
version: '6.024'
-
class: Dist::Zilla::Plugin::AutoPrereqs
name: '@Filter/AutoPrereqs'
version: '6.024'
-
class: Dist::Zilla::Plugin::ExecDir
name: '@Filter/ExecDir'
version: '6.024'
-
class: Dist::Zilla::Plugin::GatherDir
config:
Dist::Zilla::Plugin::GatherDir:
exclude_filename: []
exclude_match: []
follow_symlinks: 0
include_dotfiles: 0
prefix: ''
prune_directory: []
root: .
name: '@Filter/GatherDir'
version: '6.024'
-
class: Dist::Zilla::Plugin::License
name: '@Filter/License'
version: '6.024'
-
class: Dist::Zilla::Plugin::ManifestSkip
name: '@Filter/ManifestSkip'
version: '6.024'
-
class: Dist::Zilla::Plugin::MetaYAML
name: '@Filter/MetaYAML'
version: '6.024'
-
class: Dist::Zilla::Plugin::PruneCruft
name: '@Filter/PruneCruft'
version: '6.024'
-
class: Dist::Zilla::Plugin::Readme
name: '@Filter/Readme'
version: '6.024'
-
class: Dist::Zilla::Plugin::RunExtraTests
config:
Dist::Zilla::Role::TestRunner:
default_jobs: '4'
name: '@Filter/RunExtraTests'
version: '0.029'
-
class: Dist::Zilla::Plugin::ShareDir
name: '@Filter/ShareDir'
version: '6.024'
-
class: Dist::Zilla::Plugin::CheckChangesHasContent
name: '@Filter/CheckChangesHasContent'
version: '0.011'
-
class: Dist::Zilla::Plugin::ConfirmRelease
name: '@Filter/ConfirmRelease'
version: '6.024'
-
class: Dist::Zilla::Plugin::Manifest
name: '@Filter/Manifest'
version: '6.024'
-
class: Dist::Zilla::Plugin::MetaConfig
name: '@Filter/MetaConfig'
version: '6.024'
-
class: Dist::Zilla::Plugin::MetaJSON
name: '@Filter/MetaJSON'
version: '6.024'
-
class: Dist::Zilla::Plugin::MetaProvides::Package
config:
Dist::Zilla::Plugin::MetaProvides::Package:
finder_objects:
-
class: Dist::Zilla::Plugin::FinderCode
name: '@Filter/MetaProvides::Package/AUTOVIV/:InstallModulesPM'
version: '6.024'
include_underscores: 0
Dist::Zilla::Role::MetaProvider::Provider:
$Dist::Zilla::Role::MetaProvider::Provider::VERSION: '2.002004'
inherit_missing: '1'
inherit_version: '1'
meta_noindex: '1'
Dist::Zilla::Role::ModuleMetadata:
Module::Metadata: '1.000037'
version: '0.006'
name: '@Filter/MetaProvides::Package'
version: '2.004003'
-
class: Dist::Zilla::Plugin::MetaResources
name: '@Filter/MetaResources'
version: '6.024'
-
class: Dist::Zilla::Plugin::ModuleBuild
config:
Dist::Zilla::Role::TestRunner:
default_jobs: '4'
name: '@Filter/ModuleBuild'
version: '6.024'
-
class: Dist::Zilla::Plugin::PkgVersion
name: '@Filter/PkgVersion'
version: '6.024'
-
class: Dist::Zilla::Plugin::PodCoverageTests
name: '@Filter/PodCoverageTests'
version: '6.024'
-
class: Dist::Zilla::Plugin::PodSyntaxTests
name: '@Filter/PodSyntaxTests'
version: '6.024'
-
class: Dist::Zilla::Plugin::Test::Compile
config:
Dist::Zilla::Plugin::Test::Compile:
bail_out_on_fail: '0'
fail_on_warning: author
fake_home: 0
filename: t/00-compile.t
module_finder:
- ':InstallModules'
needs_display: 0
phase: test
script_finder:
- ':PerlExecFiles'
skips: []
switch: []
name: '@Filter/Test::Compile'
version: '2.058'
-
class: Dist::Zilla::Plugin::Test::CPAN::Changes
config:
Dist::Zilla::Plugin::Test::CPAN::Changes:
changelog: Changes
name: '@Filter/Test::CPAN::Changes'
version: '0.012'
-
class: Dist::Zilla::Plugin::Test::EOL
config:
Dist::Zilla::Plugin::Test::EOL:
filename: xt/author/eol.t
finder:
- ':ExecFiles'
- ':InstallModules'
- ':TestFiles'
trailing_whitespace: 1
name: '@Filter/Test::EOL'
version: '0.19'
-
class: Dist::Zilla::Plugin::Test::NoTabs
config:
Dist::Zilla::Plugin::Test::NoTabs:
filename: xt/author/no-tabs.t
finder:
- ':InstallModules'
- ':ExecFiles'
- ':TestFiles'
name: '@Filter/Test::NoTabs'
version: '0.15'
-
class: Dist::Zilla::Plugin::Test::TrailingSpace
name: '@Filter/Test::TrailingSpace'
version: ~
-
class: Dist::Zilla::Plugin::TestRelease
name: '@Filter/TestRelease'
version: '6.024'
-
class: Dist::Zilla::Plugin::PodWeaver
config:
Dist::Zilla::Plugin::PodWeaver:
finder:
- ':InstallModules'
- ':ExecFiles'
plugins:
-
class: Pod::Weaver::Plugin::SingleEncoding
name: '@SHLOMIF/SingleEncoding'
version: '4.018'
-
class: Pod::Weaver::Plugin::WikiDoc
name: '@SHLOMIF/WikiDoc'
version: '0.093004'
-
class: Pod::Weaver::Plugin::EnsurePod5
name: '@CorePrep/EnsurePod5'
version: '4.018'
-
class: Pod::Weaver::Plugin::H1Nester
name: '@CorePrep/H1Nester'
version: '4.018'
-
class: Pod::Weaver::Section::Generic
name: '@SHLOMIF/Name'
version: '4.018'
-
class: Pod::Weaver::Section::Version
name: '@SHLOMIF/Version'
version: '4.018'
-
class: Pod::Weaver::Section::Region
name: '@SHLOMIF/Prelude'
version: '4.018'
-
class: Pod::Weaver::Section::Generic
name: '@SHLOMIF/Synopsis'
version: '4.018'
-
class: Pod::Weaver::Section::Generic
name: '@SHLOMIF/Description'
version: '4.018'
-
class: Pod::Weaver::Section::Generic
name: '@SHLOMIF/Usage'
version: '4.018'
-
class: Pod::Weaver::Section::Generic
name: '@SHLOMIF/Overview'
version: '4.018'
-
class: Pod::Weaver::Section::Generic
name: '@SHLOMIF/Stability'
version: '4.018'
-
class: Pod::Weaver::Section::Collect
name: Requirements
version: '4.018'
-
class: Pod::Weaver::Section::Collect
name: Attributes
version: '4.018'
-
class: Pod::Weaver::Section::Collect
name: Constructors
version: '4.018'
-
class: Pod::Weaver::Section::Collect
name: Methods
version: '4.018'
-
class: Pod::Weaver::Section::Collect
name: Functions
version: '4.018'
-
class: Pod::Weaver::Section::Leftovers
name: '@SHLOMIF/Leftovers'
version: '4.018'
-
class: Pod::Weaver::Section::Region
name: '@SHLOMIF/postlude'
version: '4.018'
-
class: Pod::Weaver::Section::Support
name: '@SHLOMIF/Support'
version: '1.013'
-
class: Pod::Weaver::Section::Authors
name: '@SHLOMIF/Authors'
version: '4.018'
-
class: Pod::Weaver::Section::Bugs
name: '@SHLOMIF/Bugs'
version: '4.018'
-
class: Pod::Weaver::Section::Contributors
name: '@SHLOMIF/Contributors'
version: '0.009'
-
class: Pod::Weaver::Section::Legal
name: '@SHLOMIF/Legal'
version: '4.018'
-
class: Pod::Weaver::Plugin::Transformer
name: '@SHLOMIF/List'
version: '4.018'
name: '@Filter/PodWeaver'
version: '4.009'
-
class: Dist::Zilla::Plugin::UploadToCPAN
name: '@Filter/UploadToCPAN'
version: '6.024'
-
class: Dist::Zilla::Plugin::AutoPrereqs
name: AutoPrereqs
version: '6.024'
-
class: Dist::Zilla::Plugin::Prereqs
config:
Dist::Zilla::Plugin::Prereqs:
phase: runtime
type: requires
name: Prereqs
version: '6.024'
-
class: Dist::Zilla::Plugin::PruneCruft
name: PruneCruft
version: '6.024'
-
class: Dist::Zilla::Plugin::PruneFiles
name: PruneFiles
version: '6.024'
-
class: Dist::Zilla::Plugin::RunExtraTests
config:
Dist::Zilla::Role::TestRunner:
default_jobs: '4'
name: RunExtraTests
version: '0.029'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':InstallModules'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':IncModules'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':TestFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':ExtraTestFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':ExecFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':PerlExecFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':ShareFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':MainModule'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':AllFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: ':NoFiles'
version: '6.024'
-
class: Dist::Zilla::Plugin::FinderCode
name: '@Filter/MetaProvides::Package/AUTOVIV/:InstallModulesPM'
version: '6.024'
zilla:
class: Dist::Zilla::Dist::Builder
config:
is_trial: '0'
version: '6.024'
x_generated_by_perl: v5.34.1
x_serialization_backend: 'YAML::Tiny version 1.73'
x_spdx_expression: MIT
This archive contains the distribution AI-Pathfinding-OptimizeMultiple,
version 0.0.17:
optimize path finding searches for a large set of initial conditions (for better average performance).
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
This README file was generated by Dist::Zilla::Plugin::Readme v6.024.
bin/optimize-game-ai-multi-tasking view on Meta::CPAN
# This is for Pod::Weaver:
# PODNAME: optimize-game-ai-multi-tasking
use strict;
use warnings;
use Carp qw/ confess /;
$SIG{__WARN__} = sub {
confess( $_[0] );
};
$SIG{__DIE__} = sub {
confess( $_[0] );
};
use AI::Pathfinding::OptimizeMultiple::App::CmdLine;
my $iface =
AI::Pathfinding::OptimizeMultiple::App::CmdLine->new(
{ argv => [@ARGV], } );
$iface->run();
1;
__END__
=pod
=encoding UTF-8
bin/optimize-game-ai-multi-tasking view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple.pm view on Meta::CPAN
use PDL;
use Scalar::Util qw/ blessed /;
has chosen_scans => ( isa => 'ArrayRef', is => 'rw' );
has _iter_idx => ( isa => 'Int', is => 'rw', default => sub { 0; }, );
has _num_boards => ( isa => 'Int', is => 'ro', init_arg => 'num_boards', );
has _orig_scans_data => ( isa => 'PDL', is => 'rw' );
has _optimize_for => ( isa => 'Str', is => 'ro', init_arg => 'optimize_for', );
has _scans_data => ( isa => 'PDL', is => 'rw' );
has _selected_scans =>
( isa => 'ArrayRef', is => 'ro', init_arg => 'selected_scans', );
has _status => ( isa => 'Str', is => 'rw' );
has _quotas => ( isa => 'ArrayRef[Int]', is => 'ro', init_arg => 'quotas' );
has _total_boards_solved => ( isa => 'Int', is => 'rw' );
has _total_iters => ( is => 'rw' );
has _trace_cb =>
( isa => 'Maybe[CodeRef]', is => 'ro', init_arg => 'trace_cb' );
has _scans_meta_data => ( isa => 'ArrayRef', is => 'ro', init_arg => 'scans' );
has _scans_iters_pdls =>
( isa => 'HashRef', is => 'rw', init_arg => 'scans_iters_pdls' );
has _stats_factors => (
isa => 'HashRef',
is => 'ro',
init_arg => 'stats_factors',
default => sub { return +{}; },
);
sub BUILD
{
my $self = shift;
my $args = shift;
my $scans_data = PDL::cat(
map {
my $id = $_->id();
my $pdl = $self->_scans_iters_pdls()->{$id};
my $factor = $self->_stats_factors->{$id};
(
defined($factor)
? ( ( $pdl >= 0 ) * ( ( $pdl / $factor )->ceil() ) +
( $pdl < 0 ) * $pdl )
: $pdl
);
} @{ $self->_selected_scans() }
);
$self->_orig_scans_data($scans_data);
$self->_scans_data( $self->_orig_scans_data()->copy() );
return 0;
}
my $BOARDS_DIM = 0;
my $SCANS_DIM = 1;
my $STATISTICS_DIM = 2;
sub _next_iter_idx
{
my $self = shift;
my $ret = $self->_iter_idx();
$self->_iter_idx( $ret + 1 );
return $ret;
}
sub _get_next_quota
{
my $self = shift;
my $iter = $self->_next_iter_idx();
if ( ref( $self->_quotas() ) eq "ARRAY" )
{
return $self->_quotas()->[$iter];
}
else
{
return $self->_quotas()->($iter);
}
}
sub _calc_get_iter_state_param_method
{
my $self = shift;
my $optimize_for = $self->_optimize_for();
my %resolve = (
len => "_get_iter_state_params_len",
minmax_len => "_get_iter_state_params_minmax_len",
speed => "_get_iter_state_params_speed",
);
return $resolve{$optimize_for};
}
sub _get_iter_state_params
{
my $self = shift;
my $method = $self->_calc_get_iter_state_param_method();
return $self->$method();
}
sub _my_sum_over
{
my $pdl = shift;
return $pdl->sumover()->slice(":,(0)");
}
sub _my_xchg_sum_over
{
my $pdl = shift;
return _my_sum_over( $pdl->xchg( 0, 1 ) );
}
sub _get_iter_state_params_len
{
my $self = shift;
my $iters_quota = 0;
my $num_solved_in_iter = 0;
my $selected_scan_idx;
# If no boards were solved, then try with a larger quota
while ( $num_solved_in_iter == 0 )
{
my $q_more = $self->_get_next_quota();
if ( !defined($q_more) )
{
AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas->throw(
error => "No q_more", );
}
$iters_quota += $q_more;
my $iters = $self->_scans_data()->slice(":,:,0");
my $solved = ( ( $iters <= $iters_quota ) & ( $iters > 0 ) );
my $num_moves = $self->_scans_data->slice(":,:,2");
my $solved_moves = $solved * $num_moves;
my $solved_moves_sums = _my_sum_over($solved_moves);
my $solved_moves_counts = _my_sum_over($solved);
my $solved_moves_avgs = $solved_moves_sums / $solved_moves_counts;
( undef, undef, $selected_scan_idx, undef ) =
$solved_moves_avgs->minmaximum();
$num_solved_in_iter = $solved_moves_counts->at($selected_scan_idx);
}
return {
quota => $iters_quota,
num_solved => $num_solved_in_iter,
scan_idx => $selected_scan_idx,
};
}
sub _get_iter_state_params_minmax_len
{
my $self = shift;
my $iters_quota = 0;
my $num_solved_in_iter = 0;
my $selected_scan_idx;
# If no boards were solved, then try with a larger quota
while ( $num_solved_in_iter == 0 )
{
my $q_more = $self->_get_next_quota();
if ( !defined($q_more) )
{
AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas->throw(
error => "No q_more", );
}
$iters_quota += $q_more;
my $iters = $self->_scans_data()->slice(":,:,0");
my $solved = ( ( $iters <= $iters_quota ) & ( $iters > 0 ) );
my $num_moves = $self->_scans_data->slice(":,:,2");
my $solved_moves = $solved * $num_moves;
my $solved_moves_maxima = $solved_moves->maximum()->slice(":,(0),(0)");
my $solved_moves_counts = _my_sum_over($solved);
( undef, undef, $selected_scan_idx, undef ) =
$solved_moves_maxima->minmaximum();
$num_solved_in_iter = $solved_moves_counts->at($selected_scan_idx);
}
return {
quota => $iters_quota,
num_solved => $num_solved_in_iter,
scan_idx => $selected_scan_idx,
};
}
sub _get_iter_state_params_speed
{
my $self = shift;
my $iters_quota = 0;
my $num_solved_in_iter = 0;
my $selected_scan_idx;
# If no boards were solved, then try with a larger quota
while ( $num_solved_in_iter == 0 )
{
my $q_more = $self->_get_next_quota();
if ( !defined($q_more) )
{
AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas->throw(
error => "No q_more" );
}
$iters_quota += $q_more;
( undef, $num_solved_in_iter, undef, $selected_scan_idx ) =
PDL::minmaximum(
PDL::sumover(
( $self->_scans_data() <= $iters_quota ) &
( $self->_scans_data() > 0 )
)
);
}
return {
quota => $iters_quota,
num_solved => $num_solved_in_iter->at(0),
scan_idx => $selected_scan_idx->at(0),
};
}
sub _get_selected_scan
{
my $self = shift;
my $iter_state =
AI::Pathfinding::OptimizeMultiple::IterState->new(
$self->_get_iter_state_params(), );
$iter_state->attach_to($self);
return $iter_state;
}
sub _inspect_quota
{
my $self = shift;
my $state = $self->_get_selected_scan();
$state->register_params();
$state->update_total_iters();
if ( $self->_total_boards_solved() == $self->_num_boards() )
{
$self->_status("solved_all");
}
else
{
$state->update_idx_slice();
}
$state->detach();
}
sub calc_meta_scan
{
my $self = shift;
$self->chosen_scans( [] );
$self->_total_boards_solved(0);
$self->_total_iters(0);
$self->_status("iterating");
# $self->_inspect_quota() throws ::Error::OutOfQuotas if
# it does not have any available quotas.
eval {
while ( $self->_status() eq "iterating" )
{
$self->_inspect_quota();
}
};
if (
my $err = Exception::Class->caught(
'AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas')
)
{
$self->_status("out_of_quotas");
}
else
{
$err = Exception::Class->caught();
if ($err)
{
if ( not( blessed $err && $err->can('rethrow') ) )
{
die $err;
}
$err->rethrow;
}
}
return;
}
sub _get_num_scans
{
my $self = shift;
return ( ( $self->_scans_data()->dims() )[$SCANS_DIM] );
}
sub _calc_chosen_scan
{
my ( $self, $selected_scan_idx, $iters_quota ) = @_;
return AI::Pathfinding::OptimizeMultiple::ScanRun->new(
{
iters => (
$iters_quota * (
$self->_stats_factors->{
( $self->_selected_scans->[$selected_scan_idx]->id() ),
} // 1
)
),
scan_idx => $selected_scan_idx,
}
);
}
sub calc_flares_meta_scan
{
my $self = shift;
$self->chosen_scans( [] );
$self->_total_boards_solved(0);
$self->_total_iters(0);
$self->_status("iterating");
my $iters_quota = 0;
my $flares_num_iters = PDL::Core::pdl( [ (0) x $self->_get_num_scans() ] );
my $ones_constant =
PDL::Core::pdl( [ map { [1] } ( 1 .. $self->_get_num_scans() ) ] );
my $next_num_iters_for_each_scan_x_scan =
( ( $ones_constant x $flares_num_iters ) );
my $num_moves = $self->_scans_data->slice(":,:,1");
# The number of moves for dimension 0,1,2 above.
my $num_moves_repeat = $num_moves->clump( 1 .. 2 )->xchg( 0, 1 )
->dummy( 0, $self->_get_num_scans() );
my $selected_scan_idx;
my $loop_iter_num = 0;
my $UNSOLVED_NUM_MOVES_CONSTANT = 64 * 1024 * 1024;
my $last_avg = $UNSOLVED_NUM_MOVES_CONSTANT;
FLARES_LOOP:
while ( my $q_more = $self->_get_next_quota() )
{
$iters_quota += $q_more;
# Next number of iterations for each scan x scan combination.
my $next_num_iters = (
( $ones_constant x $flares_num_iters ) + (
PDL::MatrixOps::identity( $self->_get_num_scans() ) *
$iters_quota
)
);
# print "\$next_num_iters = $next_num_iters\n";
my $iters = $self->_scans_data()->slice(":,:,0");
my $iters_repeat =
$iters->dummy( 0, $self->_get_num_scans() )->xchg( 1, 2 )
->clump( 2 .. 3 );
# print "\$iters_repeat =", join(",",$iters_repeat->dims()), "\n";
my $next_num_iters_repeat =
$next_num_iters->dummy( 0, $self->_num_boards() )->xchg( 0, 2 );
# print "\$next_num_iters_repeat =", join(",",$next_num_iters_repeat->dims()), "\n";
# A boolean tensor of which boards were solved:
# Dimension 0 - Which scan is it. - size - _get_num_scans()
# Dimension 1 - Which scan we added the quota to
# - size - _get_num_scans()
# Dimension 2 - Which board. - size - _num_boards()
my $solved =
( $iters_repeat >= 0 ) * ( $iters_repeat < $next_num_iters_repeat );
# print "\$num_moves_repeat =", join(",",$num_moves_repeat->dims()), "\n";
my $num_moves_solved =
( $solved * $num_moves_repeat ) +
( $solved->not() * $UNSOLVED_NUM_MOVES_CONSTANT );
my $minimal_num_moves_solved =
$num_moves_solved->xchg( 0, 1 )->minimum();
my $which_minima_are_solved =
( $minimal_num_moves_solved != $UNSOLVED_NUM_MOVES_CONSTANT );
my $minimal_with_zeroes =
$which_minima_are_solved * $minimal_num_moves_solved;
my $solved_moves_sums = _my_xchg_sum_over($minimal_with_zeroes);
my $solved_moves_counts = _my_xchg_sum_over($which_minima_are_solved);
my $solved_moves_avgs = $solved_moves_sums / $solved_moves_counts;
# print join(",", $solved_moves_avgs->minmaximum()), "\n";
my $min_avg;
( $min_avg, undef, $selected_scan_idx, undef ) =
$solved_moves_avgs->minmaximum();
$last_avg = $min_avg;
push @{ $self->chosen_scans() },
$self->_calc_chosen_scan( $selected_scan_idx, $iters_quota );
$flares_num_iters->set( $selected_scan_idx,
$flares_num_iters->at($selected_scan_idx) + $iters_quota );
$self->_selected_scans()->[$selected_scan_idx]->mark_as_used();
$iters_quota = 0;
my $num_solved = $solved_moves_counts->at($selected_scan_idx);
my $flares_num_iters_repeat =
$flares_num_iters->dummy( 0, $self->_num_boards() );
# A boolean tensor:
# Dimension 0 - board.
# Dimension 1 - scans.
my $solved_with_which_iter =
( $flares_num_iters_repeat >= $iters->clump( 1 .. 2 ) ) &
( $iters->clump( 1 .. 2 ) >= 0 );
my $total_num_iters = (
( $solved_with_which_iter * $flares_num_iters_repeat )->sum() + (
$solved_with_which_iter->not()->andover() *
$flares_num_iters->sum()
)->sum()
);
print "Finished ", $loop_iter_num++,
" ; #Solved = $num_solved ; Iters = $total_num_iters ; Avg = $min_avg\n";
STDOUT->flush();
}
}
sub calc_board_iters
{
my $self = shift;
my $board = shift;
my $board_iters = 0;
my @info = PDL::list( $self->_orig_scans_data()->slice("$board,:") );
my @orig_info = @info;
foreach my $s ( @{ $self->chosen_scans() } )
{
if ( ( $info[ $s->scan_idx() ] > 0 )
&& ( $info[ $s->scan_idx() ] <= $s->iters() ) )
{
$board_iters += $info[ $s->iters() ];
last;
}
else
{
if ( $info[ $s->scan_idx() ] > 0 )
{
$info[ $s->scan_idx() ] -= $s->iters();
}
$board_iters += $s->iters();
}
}
return {
'per_scan_iters' => \@orig_info,
'board_iters' => $board_iters,
};
}
sub get_final_status
{
my $self = shift;
return $self->_status();
}
sub simulate_board
{
my ( $self, $board_idx, $args ) = @_;
if ( $board_idx !~ /\A[0-9]+\z/ )
{
die "Board index '$board_idx' is not numeric!";
}
$args ||= {};
my $chosen_scans = ( $args->{chosen_scans} || $self->chosen_scans );
my @info = PDL::list( $self->_orig_scans_data()->slice("$board_idx,:") );
my $board_iters = 0;
my @scan_runs;
my $status = "Unsolved";
my $add_new_scan_run = sub {
my $scan_run = shift;
push @scan_runs, $scan_run;
$board_iters += $scan_run->iters();
return;
};
SCANS_LOOP:
foreach my $s (@$chosen_scans)
{
if ( ( $info[ $s->scan_idx() ] > 0 )
&& ( $info[ $s->scan_idx() ] <= $s->iters() ) )
{
$add_new_scan_run->(
AI::Pathfinding::OptimizeMultiple::ScanRun->new(
{
iters => $info[ $s->scan_idx() ],
scan_idx => $s->scan_idx(),
},
)
);
$status = "Solved";
last SCANS_LOOP;
}
else
{
if ( $info[ $s->scan_idx() ] > 0 )
{
$info[ $s->scan_idx() ] -= $s->iters();
}
$add_new_scan_run->(
AI::Pathfinding::OptimizeMultiple::ScanRun->new(
{
iters => $s->iters(),
scan_idx => $s->scan_idx(),
},
)
);
}
}
return AI::Pathfinding::OptimizeMultiple::SimulationResults->new(
{
status => $status,
scan_runs => \@scan_runs,
total_iters => $board_iters,
}
);
}
sub _trace
{
my ( $self, $args ) = @_;
if ( my $trace_callback = $self->_trace_cb() )
{
$trace_callback->($args);
}
return;
}
sub get_total_iters
{
my $self = shift;
return $self->_total_iters();
}
sub _add_to_total_iters
{
my $self = shift;
my $how_much = shift;
$self->_total_iters( $self->_total_iters() + $how_much );
return;
}
sub _add_to_total_boards_solved
{
my $self = shift;
my $how_much = shift;
$self->_total_boards_solved( $self->_total_boards_solved() + $how_much );
return;
}
1; # End of AI::Pathfinding::OptimizeMultiple
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple.pm view on Meta::CPAN
AI::Pathfinding::OptimizeMultiple - optimize path finding searches for a large
set of initial conditions (for better average performance).
=head1 VERSION
version 0.0.17
=head1 SYNOPSIS
use AI::Pathfinding::OptimizeMultiple
my @scans =
(
{
name => "first_search"
},
{
name => "second_search",
},
{
name => "third_search",
},
);
my $obj = AI::Pathfinding::OptimizeMultiple->new(
{
scans => \@scans,
num_boards => 32_000,
optimize_for => 'speed',
scans_iters_pdls =>
{
first_search => $first_search_pdl,
second_search => $second_search_pdl,
},
quotas => [400, 300, 200],
selected_scans =>
[
AI::Pathfinding::OptimizeMultiple::Scan->new(
id => 'first_search',
cmd_line => "--preset first_search",
),
AI::Pathfinding::OptimizeMultiple::Scan->new(
id => 'second_search',
cmd_line => "--preset second_search",
),
AI::Pathfinding::OptimizeMultiple::Scan->new(
id => 'third_search',
cmd_line => "--preset third_search",
),
],
}
);
$obj->calc_meta_scan();
foreach my $scan_alloc (@{$self->chosen_scans()})
{
printf "Run %s for %d iterations.\n",
$scans[$scan_alloc->scan_idx], $scan_alloc->iters;
}
=head1 DESCRIPTION
This CPAN distribution implements the algorithm described here:
=over 4
=item * L<https://groups.google.com/group/comp.ai.games/msg/41e899e9beea5583?dmode=source&output=gplain&noredirect>
=item * L<http://www.shlomifish.org/lecture/Perl/Lightning/Opt-Multi-Task-in-PDL/>
lib/AI/Pathfinding/OptimizeMultiple.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm view on Meta::CPAN
# TODO : restore later.
# use MyInput;
use Carp ();
has argv => ( isa => 'ArrayRef[Str]', is => 'ro', required => 1, );
has _arbitrator => ( is => 'rw' );
has _add_horne_prune => ( isa => 'Bool', is => 'rw' );
has _chosen_scans => ( isa => 'ArrayRef', is => 'rw' );
has _should_exit_immediately =>
( isa => 'Bool', is => 'rw', default => sub { 0; }, );
has input_obj_class => ( isa => 'Str', is => 'rw' );
has _input_obj => ( is => 'rw' );
has _is_flares => ( is => 'rw', isa => 'Bool', default => sub { 0; }, );
has _num_boards => ( isa => 'Int', is => 'rw' );
has _offset_quotas => ( isa => 'Int', is => 'rw' );
has _optimize_for => ( isa => 'Str', is => 'rw' );
has _output_filename => ( isa => 'Str', is => 'rw' );
has _post_processor => (
isa => 'Maybe[AI::Pathfinding::OptimizeMultiple::PostProcessor]',
is => 'rw'
);
has _quotas_are_cb => ( isa => 'Bool', is => 'rw' );
has _quotas_expr => ( isa => 'Maybe[Str]', is => 'rw' );
has _should_rle_be_done => ( isa => 'Bool', is => 'rw' );
has _should_trace_be_done => ( isa => 'Bool', is => 'rw' );
has _simulate_to => ( isa => 'Maybe[Str]', is => 'rw' );
has _start_board => ( isa => 'Int', is => 'rw' );
has _stats_factors =>
( isa => 'HashRef', is => 'rw', default => sub { return +{}; }, );
my $_component_re = qr/[A-Za-z][A-Za-z0-9_]*/;
my $_module_re = qr/$_component_re(?:::$_component_re)*/;
sub BUILD
{
my $self = shift;
# Command line parameters
my $_start_board = 1;
my $num_boards = 32000;
my $output_filename = "-";
my $should_trace_be_done = 0;
my $should_rle_be_done = 1;
my $_quotas_expr = undef;
my $quotas_are_cb = 0;
my $optimize_for = "speed";
my $offset_quotas = 0;
my $simulate_to = undef;
my $_add_horne_prune = 0;
my $input_obj_class = 'AI::Pathfinding::OptimizeMultiple::DataInputObj';
my %stats_factors;
my $help = 0;
my $man = 0;
GetOptionsFromArray(
$self->argv(),
'help|h' => \$help,
man => \$man,
"o|output=s" => \$output_filename,
"num-boards=i" => \$num_boards,
"trace" => \$should_trace_be_done,
"rle!" => \$should_rle_be_done,
"start-board=i" => \$_start_board,
"quotas-expr=s" => \$_quotas_expr,
"quotas-are-cb" => \$quotas_are_cb,
"offset-quotas" => \$offset_quotas,
"opt-for=s" => \$optimize_for,
"simulate-to=s" => \$simulate_to,
"sprtf" => \$_add_horne_prune,
"input-class=s" => \$input_obj_class,
"stats-factors=f" => \%stats_factors,
) or die "Extracting options from ARGV array failed - $!";
if ($help)
{
$self->_should_exit_immediately(1);
print <<"EOF";
$0 - optimize a game AI multi-tasking configuration
--help | -h - displays this help screen
--output=[filename] | -o [filename] - output to this file instead of STDOUT.
EOF
return;
}
$self->_start_board($_start_board);
$self->_num_boards($num_boards);
$self->_output_filename($output_filename);
$self->_should_trace_be_done($should_trace_be_done);
$self->_should_rle_be_done($should_rle_be_done);
$self->_quotas_expr($_quotas_expr);
$self->_quotas_are_cb($quotas_are_cb);
$self->_optimize_for($optimize_for);
$self->_offset_quotas($offset_quotas);
$self->_simulate_to($simulate_to);
$self->_add_horne_prune($_add_horne_prune);
$self->_stats_factors( \%stats_factors );
$self->input_obj_class($input_obj_class);
{
my $class = $self->input_obj_class();
if ( $class !~ m{\A$_module_re\z} )
{
Carp::confess(
"Input object class does not seem like a good class:"
. $self->input_obj_class() );
}
eval "require $class;";
if ($@)
{
die "Could not load '$class' - <<$@>>";
}
# TODO : Restore later.
$self->_input_obj(
$class->new(
{
start_board => $self->_start_board(),
num_boards => $self->_num_boards(),
}
)
);
}
$self->_post_processor(
AI::Pathfinding::OptimizeMultiple::PostProcessor->new(
{
do_rle => $self->_should_rle_be_done(),
offset_quotas => $self->_offset_quotas(),
}
)
);
return;
}
sub _selected_scans
{
my $self = shift;
return $self->_input_obj->selected_scans();
}
sub _map_all_but_last
{
my $self = shift;
my ( $cb, $arr_ref ) = (@_);
return [
( map { $cb->($_) } @$arr_ref[ 0 .. $#$arr_ref - 1 ] ),
$arr_ref->[-1]
];
}
sub _get_quotas
{
my $self = shift;
if ( $self->_quotas_are_cb() )
{
return scalar( eval( $self->_quotas_expr() ) );
}
elsif ( defined( $self->_quotas_expr() ) )
{
return [ eval $self->_quotas_expr() ];
}
else
{
return $self->_get_default_quotas();
}
}
sub _get_default_quotas
{
return [ (350) x 5000 ];
}
sub _get_script_fh
{
my $self = shift;
return IO::File->new(
( $self->_output_filename() eq "-" )
? ">&STDOUT"
: ( $self->_output_filename(), "w" )
);
}
sub _get_script_terminator
{
return "\n\n\n";
}
sub _out_script
{
my $self = shift;
my $cmd_line_string = shift;
$self->_get_script_fh()
->print( $cmd_line_string,
$self->_get_script_terminator($cmd_line_string) );
}
sub _get_line_of_command
{
my $self = shift;
my $args_string = join( " ",
$self->_start_board(),
$self->_start_board() + $self->_num_boards() - 1, 1 );
return "freecell-solver-range-parallel-solve $args_string";
}
sub _line_ends_mapping
{
my $self = shift;
return $self->_map_all_but_last( sub { "$_[0] \\\n" }, shift );
}
sub _get_used_scans
{
my $self = shift;
return [ grep { $_->is_used() } @{ $self->_selected_scans() } ];
}
sub _get_scan_line
{
my ( $self, $line ) = @_;
return
$line->{'cmd_line'}
. " -step 500 "
. join( " ",
map { $_, $line->{'id'} }
( "--st-name", ( $self->_is_flares() ? "--flare-name" : () ) ) );
}
sub _get_lines_of_scan_defs
{
my $self = shift;
return [ map { $self->_get_scan_line($_) } @{ $self->_get_used_scans() } ];
}
sub _scan_def_line_mapping
{
my ( $self, $lines_aref ) = @_;
return $self->_map_all_but_last(
sub {
my ($line) = @_;
return $line . ' ' . ( $self->_is_flares() ? "-nf" : "-nst" );
},
[
map {
my $line = $_;
# Add the -sp r:tf flag to each scan if specified - it enhances
# performance, but timing the scans with it makes the total
# scan sub-optimal.
if ( $self->_add_horne_prune() )
{
$line =~ s/( --st-name)/ -sp r:tf$1/;
}
$line;
} @$lines_aref
],
);
}
sub _calc_iter_quota
{
my $self = shift;
my $quota = shift;
if ( $self->_offset_quotas() )
{
return $quota + 1;
}
else
{
return $quota;
}
}
sub _map_scan_idx_to_id
{
my $self = shift;
my $index = shift;
return $self->_selected_scans()->[$index]->id();
}
sub _format_prelude_iter
{
my $self = shift;
my $iter = shift;
return
( $self->_is_flares() ? "Run:" : "" )
. $iter->iters() . '@'
. $self->_map_scan_idx_to_id( $iter->scan_idx() );
}
sub _get_line_of_prelude
{
my $self = shift;
return
+( $self->_is_flares() ? "--flares-plan" : "--prelude" ) . qq{ "}
. join( ",",
map { $self->_format_prelude_iter($_) } @{ $self->_chosen_scans() } )
. "\"";
}
sub _calc_script_lines
{
my $self = shift;
return [
$self->_get_line_of_command(),
@{
$self->_scan_def_line_mapping( $self->_get_lines_of_scan_defs() )
},
$self->_get_line_of_prelude()
];
}
sub _calc_script_text
{
my $self = shift;
return join( "",
@{ $self->_line_ends_mapping( $self->_calc_script_lines() ) } );
}
sub _write_script
{
my $self = shift;
$self->_out_script( $self->_calc_script_text() );
}
sub _calc_scans_iters_pdls
{
my $self = shift;
my $method = (
( $self->_optimize_for() =~ m{len} )
? "get_scans_lens_iters_pdls"
: "get_scans_iters_pdls"
);
return $self->_input_obj->$method();
}
sub _arbitrator_trace_cb
{
my $args = shift;
printf( "%s \@ %s (%s solved)\n",
@$args{qw(iters_quota selected_scan_idx total_boards_solved)} );
}
sub _init_arbitrator
{
my $self = shift;
return $self->_arbitrator(
AI::Pathfinding::OptimizeMultiple->new(
{
'scans' => [
map { +{ name => $_->id() } }
@{ $self->_input_obj->_suitable_scans_list() },
],
'quotas' => $self->_get_quotas(),
'selected_scans' => $self->_selected_scans(),
'num_boards' => $self->_num_boards(),
'scans_iters_pdls' => $self->_calc_scans_iters_pdls(),
'trace_cb' => \&_arbitrator_trace_cb,
'optimize_for' => $self->_optimize_for(),
'stats_factors' => $self->_stats_factors(),
}
)
);
}
sub _report_total_iters
{
my $self = shift;
if ( $self->_arbitrator()->get_final_status() eq "solved_all" )
{
print "Solved all!\n";
}
printf( "total_iters = %s\n", $self->_arbitrator()->get_total_iters() );
}
sub _arbitrator_process
{
my $self = shift;
$self->_arbitrator()->calc_meta_scan();
my $scans =
$self->_post_processor->process( $self->_arbitrator->chosen_scans() );
$self->_chosen_scans($scans);
}
sub _do_trace_for_board
{
my $self = shift;
my $board = shift;
my $results = $self->_arbitrator()->calc_board_iters($board);
print "\@info=" . join( ",", @{ $results->{per_scan_iters} } ) . "\n";
print +( $board + $self->_start_board() ) . ": "
. $results->{board_iters} . "\n";
}
sub _real_do_trace
{
my $self = shift;
foreach my $board ( 0 .. $self->_num_boards() - 1 )
{
$self->_do_trace_for_board($board);
}
}
sub _do_trace
{
my $self = shift;
# Analyze the results
if ( $self->_should_trace_be_done() )
{
$self->_real_do_trace();
}
}
sub _get_run_string
{
my $self = shift;
my $results = shift;
return join(
"",
map {
sprintf( '%i@%i,',
$_->iters(), $self->_map_scan_idx_to_id( $_->scan_idx() ) )
} @{ $self->_post_processor->process( $results->scan_runs() ) },
);
}
sub _do_simulation_for_board
{
my ( $self, $board ) = @_;
my $results = $self->_arbitrator()->simulate_board($board);
my $scan_mapper = sub {
my $index = shift;
return $self->_map_scan_idx_to_id($index);
};
return sprintf( "%i:%s:%s:%i",
$board + 1,
$results->get_status(),
$self->_get_run_string($results),
$results->get_total_iters(),
);
}
sub _real_do_simulation
{
my $self = shift;
open my $simulate_out_fh, ">", $self->_simulate_to()
or Carp::confess( "Could not open " . $self->_simulate_to() . " - $!" );
foreach my $board ( 0 .. $self->_num_boards() - 1 )
{
print {$simulate_out_fh} $self->_do_simulation_for_board($board), "\n";
}
close($simulate_out_fh);
return;
}
sub _do_simulation
{
my $self = shift;
# Analyze the results
if ( defined( $self->_simulate_to() ) )
{
$self->_real_do_simulation();
}
return;
}
sub run
{
my $self = shift;
if ( $self->_should_exit_immediately() )
{
return 0;
}
$self->_init_arbitrator();
$self->_arbitrator_process();
$self->_report_total_iters();
$self->_write_script();
$self->_do_trace();
$self->_do_simulation();
return 0;
}
sub run_flares
{
my $self = shift;
$self->_optimize_for("len");
$self->_is_flares(1);
$self->_init_arbitrator();
$self->_arbitrator()->calc_flares_meta_scan();
my $scans =
$self->_post_processor->process( $self->_arbitrator->chosen_scans() );
$self->_chosen_scans($scans);
$self->_report_total_iters();
$self->_write_script();
$self->_do_trace();
$self->_do_simulation();
return 0;
}
1;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/DataInputObj.pm view on Meta::CPAN
use File::Path qw(mkpath);
use AI::Pathfinding::OptimizeMultiple::Scan ();
use PDL (qw( pdl ));
use PDL::IO::FastRaw (qw( readfraw writefraw ));
has start_board => ( isa => 'Int', is => 'ro', required => 1 );
has num_boards => ( isa => 'Int', is => 'ro', required => 1 );
has selected_scans => (
isa => 'ArrayRef',
is => 'ro',
required => 1,
default => sub {
my ($self) = @_;
return $self->_calc_selected_scan_list();
},
lazy => 1,
);
has _scan_ids_to_indexes => (
isa => 'HashRef[Int]',
is => 'ro',
lazy => 1,
default => sub {
my ($self) = @_;
my $scan_ids = $self->get_scan_ids_aref;
return +{ map { $scan_ids->[$_] => $_ } 0 .. $#$scan_ids };
},
);
sub _slurp
{
my $filename = shift;
open my $in, "<", $filename
or die "Could not open $filename";
binmode $in;
local $/;
my $content = <$in>;
close($in);
return $content;
}
sub _read_text_ints_file
{
my $self = shift;
my $filename = shift;
my $text = _slurp($filename);
return [ split( /[\n\r]+/, $text ) ];
}
# Number of selected scans.
sub _num_sel_scans
{
my $self = shift;
return scalar( @{ $self->selected_scans() } );
}
sub _gen_initial_scans_tensor
{
my $self = shift;
my $extra_dims = shift || [];
return zeroes( $self->num_boards(), $self->_num_sel_scans, @$extra_dims );
}
sub _should_update
{
my ( $self, $src_path, $dest_path ) = @_;
my @orig_stat = stat($src_path);
my @proc_stat = stat($dest_path);
return ( ( !@proc_stat ) || ( $orig_stat[9] > $proc_stat[9] ) );
}
# Number of numbers in the header of the solutions' iteration counts
my $NUM_NUMBERS_IN_HEADER = 3;
my $HEADER_START_BOARD_IDX = 0;
my $HEADER_NUM_BOARDS = 1;
my $HEADER_ITERATIONS_LIMIT = 2;
sub _get_scans_data_helper
{
my $self = shift;
my $selected_scans = $self->selected_scans();
my $start_board = $self->start_board();
my $scans_data = {};
my $scans_lens_data = {};
my $data_dir = ".data-proc";
my $lens_dir = ".data-len-proc";
mkpath( [ $data_dir, $lens_dir ] );
foreach my $scan (@$selected_scans)
{
{
my $dest_path = $data_dir . "/" . $scan->id();
{
if (
$self->_should_update(
$scan->data_file_path(), $dest_path
)
)
{
my $data_s = _slurp( $scan->data_file_path() );
my @array = unpack( "l*", $data_s );
if ( ( $array[$HEADER_START_BOARD_IDX] != 1 )
|| ( $array[$HEADER_NUM_BOARDS] < $self->num_boards ) )
{
die "Incorrect file format in scan "
. $scan->{'id'} . "!\n";
}
my $c = pdl( \@array );
writefraw( $c, $dest_path );
}
}
{
my $start_idx = $NUM_NUMBERS_IN_HEADER + ( $start_board - 1 );
my $scan_vec = readfraw($dest_path);
$scans_data->{ $scan->id() } =
$scan_vec->slice( $start_idx . ":"
. ( $start_idx + $self->num_boards() - 1 ) );
}
}
{
my $src = $scan->data_file_path();
my $dest = "$lens_dir/" . $scan->id();
if ( $self->_should_update( $src, $dest ) )
{
my $data_s = _slurp($src);
my @iters = unpack( "l*", $data_s );
if ( ( $iters[0] != 1 ) || ( $iters[1] < $self->num_boards() ) )
{
die "Incorrect file format in scan " . $scan->id() . "!\n";
}
# Remove the header
splice @iters, 0, $NUM_NUMBERS_IN_HEADER;
my $c = pdl(
[
\@iters,
$self->_read_text_ints_file(
"data/" . $scan->id() . ".fcs.moves.txt"
),
$self->_read_text_ints_file(
"data/" . $scan->id() . ".fcpro.moves.txt"
),
]
);
writefraw( $c, $dest );
}
{
my $scan_vec = readfraw($dest);
$scans_lens_data->{ $scan->id() } = $scan_vec->slice(
sprintf( "%d:%d,:,*",
( $start_board - 1 ),
( ( $self->num_boards() - 1 ) + ( $start_board - 1 ) ) )
)->xchg( 1, 2 );
}
}
}
return { 'scans' => $scans_data, 'with_lens' => $scans_lens_data };
}
sub _get_scans_data_generic
{
my ( $self, $id ) = @_;
return $self->_get_scans_data_helper()->{$id};
}
sub get_scans_iters_pdls
{
my $self = shift;
return $self->_get_scans_data_generic('scans');
}
sub get_scans_lens_iters_pdls
{
my $self = shift;
return $self->_get_scans_data_generic('with_lens');
}
sub _filter_scans_based_on_black_list_ids
{
my ( $scans, $black_list_ids ) = @_;
my %black_list = ( map { /(\d+)/ ? ( $1 => 1 ) : () } @$black_list_ids );
return [ grep { !exists( $black_list{ $_->id() } ) } @$scans ];
}
sub _is_scan_suitable
{
my ( $self, $scan ) = @_;
my @stat = stat( $scan->data_file_path() );
return (
scalar(@stat)
&& ( $stat[7] >=
12 + ( $self->num_boards() + $self->start_board() - 1 ) * 4 )
);
}
sub _get_scans_registry_file_path
{
return "scans.txt";
}
sub _get_all_scans_list_from_file
{
my $self = shift;
my @scans;
my $scans_fn = $self->_get_scans_registry_file_path;
open my $scans_fh, "<", $scans_fn
or die "Could not open '$scans_fn' - $!.";
while ( my $line = <$scans_fh> )
{
chomp($line);
my ( $id, $cmd_line ) = split( /\t/, $line );
push @scans,
AI::Pathfinding::OptimizeMultiple::Scan->new(
id => $id,
cmd_line => $cmd_line
);
}
close($scans_fh);
return \@scans;
}
sub _black_list_ids_list
{
my $self = shift;
open my $black_list_fh, "<", "scans-black-list.txt"
or die "Could not open 'scans-black-list.txt'! $!.";
my @black_list_ids = <$black_list_fh>;
chomp(@black_list_ids);
close($black_list_fh);
return \@black_list_ids;
}
sub _suitable_scans_list
{
my $self = shift;
return [ grep { $self->_is_scan_suitable($_) }
@{ $self->_get_all_scans_list_from_file() } ];
}
sub _calc_selected_scan_list
{
my $self = shift;
return _filter_scans_based_on_black_list_ids(
$self->_suitable_scans_list(),
$self->_black_list_ids_list(),
);
}
sub _get_next_id_file_path
{
return "next-id.txt";
}
sub get_next_id
{
my ($self) = @_;
my $id;
my $fn = $self->_get_next_id_file_path;
use autodie;
open my $in, "<", $fn;
$id = <$in>;
chomp($id);
close($in);
open my $out, ">", $fn;
print {$out} ( $id + 1 );
close($out);
return $id;
}
sub get_prev_scans
{
my ($self) = @_;
my @prev_scans;
my $scans_fn = $self->_get_scans_registry_file_path;
open my $in, "<", $scans_fn
or die "Could not open '$scans_fn' - $!.";
while ( my $line = <$in> )
{
chomp($line);
my ( $scan_id, $cmd_line ) = split( /\t/, $line );
push @prev_scans, { 'id' => $scan_id, 'cmd_line' => $cmd_line };
}
close($in);
return \@prev_scans;
}
sub _get_scan_cmd_line
{
my $self = shift;
my $args = shift;
my $min_board = $args->{'min'} || 1;
my $max_board = $args->{'max'} || 32_000;
my $id = $args->{'id'};
my $argv = $args->{'argv'};
my @fc_num = (
exists( $args->{'freecells_num'} )
? ( "--freecells-num", $args->{'freecells_num'} )
: ()
);
my @variant = (
exists( $args->{'variant'} )
? ( "--variant", $args->{'variant'} )
: ()
);
return [
qw(freecell-solver-fc-pro-range-solve),
$min_board,
$max_board,
"20",
@variant,
'--total-iterations-limit',
( $ENV{FC_SOLVE_RANGE_ITERS_LIMIT} // 100000 ),
'--binary-output-to',
"data/$id.data.bin",
@$argv,
@fc_num,
];
}
sub time_scan
{
my $self = shift;
my $args = shift;
my $min_board = $args->{'min'} || 1;
my $max_board = $args->{'max'} || 32_000;
my $id = $args->{'id'};
my $cmd_line = $self->_get_scan_cmd_line($args);
open my $from_cmd, "-|", @$cmd_line
or die "Could not start '@$cmd_line'";
open my $fcs_out, ">", "data/$id.fcs.moves.txt";
open my $fc_pro_out, ">", "data/$id.fcpro.moves.txt";
$fcs_out->autoflush(1);
$fc_pro_out->autoflush(1);
while ( my $line = <$from_cmd> )
{
print $line;
chomp($line);
if ( $line =~ m{\A\[\[Num FCS Moves\]\]=(.*)\z}o )
{
print {$fcs_out} "$1\n";
}
elsif ( $line =~ m{\A\[\[Num FCPro Moves\]\]=(.*)\z}o )
{
print {$fc_pro_out} "$1\n";
}
}
close($from_cmd);
close($fcs_out);
close($fc_pro_out);
}
sub get_scan_ids_aref
{
my $self = shift;
return [ map { $_->id() } @{ $self->selected_scans } ];
}
sub lookup_scan_idx_based_on_id
{
my ( $self, $scan_id ) = @_;
my $idx = $self->_scan_ids_to_indexes->{$scan_id};
if ( !defined($idx) )
{
die "Index '$idx' does not exist!";
}
return $idx;
}
1;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/DataInputObj.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/IterState.pm view on Meta::CPAN
use 5.012;
use MooX qw/late/;
use PDL ();
use vars (qw(@fields));
has _main => ( is => 'rw' );
has _num_solved =>
( isa => 'Int', is => 'ro', init_arg => 'num_solved', required => 1 );
has _quota => ( isa => 'Int', is => 'ro', init_arg => 'quota', required => 1 );
has _scan_idx =>
( isa => 'Int', is => 'ro', init_arg => 'scan_idx', required => 1 );
use Exception::Class ('AI::Pathfinding::OptimizeMultiple::Error::OutOfQuotas');
sub attach_to
{
my $self = shift;
my $main_obj = shift;
$self->_main($main_obj);
return;
}
sub get_chosen_struct
{
my $self = shift;
return $self->_main->_calc_chosen_scan( $self->_scan_idx, $self->_quota );
}
sub detach
{
my $self = shift;
$self->_main(undef);
}
sub idx_slice
{
my $self = shift;
my $scans_data = $self->_main()->_scans_data();
my @dims = $scans_data->dims();
return $scans_data->slice(
join( ",", ":", $self->_scan_idx(), ( ("(0)") x ( @dims - 2 ) ) ) );
}
sub update_total_iters
{
my $state = shift;
# $r is the result of this scan.
my $r = $state->idx_slice();
# Add the total iterations for all the states that were solved by
# this scan.
$state->_main()
->_add_to_total_iters(
PDL::sum( ( ( $r <= $state->_quota() ) & ( $r > 0 ) ) * $r ) );
# Find all the states that weren't solved.
my $indexes = PDL::which( ( $r > $state->_quota() ) | ( $r < 0 ) );
# Add the iterations for all the states that have not been solved
# yet.
$state->_main()
->_add_to_total_iters( $indexes->nelem() * $state->_quota() );
# Keep only the states that have not been solved yet.
$state->_main()
->_scans_data(
$state->_main()->_scans_data()->dice( $indexes, "X" )->copy() );
}
sub update_idx_slice
{
my $state = shift;
my $r = $state->idx_slice()->copy();
# $r cannot be 0, because the ones that were 0, were already solved
# in $state->update_total_iters().
my $idx_slice = $state->idx_slice();
$idx_slice .=
( ( $r > 0 ) * ( $r - $state->_quota() ) ) + ( ( $r < 0 ) * ($r) );
}
sub _mark_as_used
{
my $state = shift;
$state->_main()->_selected_scans()->[ $state->_scan_idx() ]->mark_as_used();
return;
}
sub _add_chosen
{
my $state = shift;
push @{ $state->_main()->chosen_scans() }, $state->get_chosen_struct();
return;
}
sub _update_total_boards_solved
{
my $state = shift;
$state->_main()->_add_to_total_boards_solved( $state->_num_solved() );
return;
}
sub _trace_wrapper
{
my $state = shift;
$state->_main()->_trace(
{
'iters_quota' => $state->_quota(),
'selected_scan_idx' => $state->_scan_idx(),
'total_boards_solved' => $state->_main()->_total_boards_solved(),
}
);
return;
}
sub register_params
{
my $state = shift;
$state->_add_chosen();
$state->_mark_as_used();
$state->_update_total_boards_solved();
$state->_trace_wrapper();
return;
}
1;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/IterState.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/PostProcessor.pm view on Meta::CPAN
package AI::Pathfinding::OptimizeMultiple::PostProcessor;
$AI::Pathfinding::OptimizeMultiple::PostProcessor::VERSION = '0.0.17';
use strict;
use warnings;
use 5.012;
use MooX qw/late/;
has _should_do_rle =>
( isa => 'Bool', is => 'ro', init_arg => 'do_rle', required => 1 );
has _offset_quotas => (
isa => 'Bool',
is => 'ro',
init_arg => 'offset_quotas',
required => 1
);
sub scans_rle
{
my $self = shift;
my @scans_list = @{ shift() };
my $scan = shift(@scans_list);
my (@a);
while ( my $next_scan = shift(@scans_list) )
{
if ( $next_scan->scan_idx() == $scan->scan_idx() )
{
$scan->iters( $scan->iters() + $next_scan->iters() );
}
else
{
push @a, $scan;
$scan = $next_scan;
}
}
push @a, $scan;
return \@a;
}
sub process
{
my $self = shift;
my $scans_orig = shift;
# clone the scans.
my $scans = [ map { $_->clone(); } @{$scans_orig} ];
if ( $self->_offset_quotas )
{
$scans = [
map {
my $ret = $_->clone();
$ret->iters( $ret->iters() + 1 );
$ret;
} @$scans
];
}
if ( $self->_should_do_rle )
{
$scans = $self->scans_rle($scans);
}
return $scans;
}
1;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/PostProcessor.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/Scan.pm view on Meta::CPAN
use 5.012;
use MooX qw/late/;
has cmd_line => ( isa => 'Str', is => 'ro', required => 1, );
has id => ( isa => 'Str', is => 'ro', required => 1, );
has used => ( isa => 'Bool', is => 'rw', default => sub { 0; } );
sub mark_as_used
{
my $self = shift;
$self->used(1);
}
sub is_used
{
my $self = shift;
return $self->used();
}
sub data_file_path
{
my $self = shift;
return "./data/" . $self->id() . ".data.bin";
}
1;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/Scan.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm view on Meta::CPAN
use 5.012;
use MooX qw/late/;
has iters => ( isa => 'Int', is => 'rw', required => 1 );
has scan_idx => ( isa => 'Int', is => 'ro', required => 1 );
sub clone
{
my $self = shift;
return ref($self)->new(
{
iters => $self->iters(),
scan_idx => $self->scan_idx(),
}
);
}
1; # End of AI::Pathfinding::OptimizeMultiple::ScanRun;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm view on Meta::CPAN
AI::Pathfinding::OptimizeMultiple::ScanRun - running scan_idx for certain
iterations.
=head1 VERSION
version 0.0.17
=head1 SYNOPSIS
printf "Run %s for %d iterations.\n",
$scans[$scan_alloc->scan_idx], $scan_alloc->iters;
=head1 DESCRIPTION
A class for scan iterations.
=head1 SLOTS
=head2 $scan_run->scan_idx()
The index of the scan (not the ID/name).
lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
lib/AI/Pathfinding/OptimizeMultiple/SimulationResults.pm view on Meta::CPAN
use strict;
use warnings;
use 5.012;
use MooX qw/late/;
has status => ( isa => 'Str', is => 'ro', required => 1, );
has total_iters => ( isa => 'Int', is => 'ro', required => 1, );
has scan_runs => (
isa => 'ArrayRef[AI::Pathfinding::OptimizeMultiple::ScanRun]',
is => 'ro',
required => 1,
);
sub get_total_iters
{
return shift->total_iters();
}
sub get_status
{
return shift->status();
}
1;
__END__
=pod
=encoding UTF-8
lib/AI/Pathfinding/OptimizeMultiple/SimulationResults.pm view on Meta::CPAN
progress on the request by the system.
=head2 Source Code
The code is open to the world, and available for you to hack on. Please feel free to browse it and play
with it, or whatever. If you want to contribute patches, please send me a diff or prod me to pull
from your repository :)
L<http://github.com/shlomif/fc-solve>
git clone ssh://git@github.com/shlomif/fc-solve.git
=head1 AUTHOR
Shlomi Fish <shlomif@cpan.org>
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/shlomif/fc-solve/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2012 by Shlomi Fish.
This is free software, licensed under:
The MIT (X11) License
=cut
rejects.pod view on Meta::CPAN
=head1 BUGS
Please report any bugs or feature requests to C<bug-ai-pathfinding-optimizemultiple at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=AI-Pathfinding-OptimizeMultiple>. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc AI::Pathfinding::OptimizeMultiple
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Games-AI-Pathfinding-OptimizeMultiple>
=item * CPAN Ratings
t/00-compile.t view on Meta::CPAN
use strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::Compile 2.058
use Test::More;
plan tests => 9 + ($ENV{AUTHOR_TESTING} ? 1 : 0);
my @module_files = (
'AI/Pathfinding/OptimizeMultiple.pm',
'AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm',
'AI/Pathfinding/OptimizeMultiple/DataInputObj.pm',
'AI/Pathfinding/OptimizeMultiple/IterState.pm',
'AI/Pathfinding/OptimizeMultiple/PostProcessor.pm',
'AI/Pathfinding/OptimizeMultiple/Scan.pm',
'AI/Pathfinding/OptimizeMultiple/ScanRun.pm',
'AI/Pathfinding/OptimizeMultiple/SimulationResults.pm'
);
my @scripts = (
'bin/optimize-game-ai-multi-tasking'
);
# no fake home requested
my @switches = (
-d 'blib' ? '-Mblib' : '-Ilib',
);
use File::Spec;
use IPC::Open3;
use IO::Handle;
open my $stdin, '<', File::Spec->devnull or die "can't open devnull: $!";
my @warnings;
for my $lib (@module_files)
{
# see L<perlfaq8/How can I capture STDERR from an external command?>
my $stderr = IO::Handle->new;
diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} }
$^X, @switches, '-e', "require q[$lib]"))
if $ENV{PERL_COMPILE_TEST_DEBUG};
my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-e', "require q[$lib]");
binmode $stderr, ':crlf' if $^O eq 'MSWin32';
my @_warnings = <$stderr>;
waitpid($pid, 0);
is($?, 0, "$lib loaded ok");
shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/
and not eval { +require blib; blib->VERSION('1.01') };
if (@_warnings)
{
warn @_warnings;
push @warnings, @_warnings;
}
}
foreach my $file (@scripts)
{ SKIP: {
open my $fh, '<', $file or warn("Unable to open $file: $!"), next;
my $line = <$fh>;
close $fh and skip("$file isn't perl", 1) unless $line =~ /^#!\s*(?:\S*perl\S*)((?:\s+-\w*)*)(?:\s*#.*)?$/;
@switches = (@switches, split(' ', $1)) if $1;
close $fh and skip("$file uses -T; not testable with PERL5LIB", 1)
if grep { $_ eq '-T' } @switches and $ENV{PERL5LIB};
my $stderr = IO::Handle->new;
diag('Running: ', join(', ', map { my $str = $_; $str =~ s/'/\\'/g; q{'} . $str . q{'} }
$^X, @switches, '-c', $file))
if $ENV{PERL_COMPILE_TEST_DEBUG};
my $pid = open3($stdin, '>&STDERR', $stderr, $^X, @switches, '-c', $file);
binmode $stderr, ':crlf' if $^O eq 'MSWin32';
my @_warnings = <$stderr>;
waitpid($pid, 0);
is($?, 0, "$file compiled ok");
shift @_warnings if @_warnings and $_warnings[0] =~ /^Using .*\bblib/
and not eval { +require blib; blib->VERSION('1.01') };
# in older perls, -c output is simply the file portion of the path being tested
if (@_warnings = grep { !/\bsyntax OK$/ }
grep { chomp; $_ ne (File::Spec->splitpath($file))[2] } @_warnings)
{
warn @_warnings;
push @warnings, @_warnings;
}
} }
is(scalar(@warnings), 0, 'no warnings found')
or diag 'got warnings: ', ( Test::More->can('explain') ? Test::More::explain(\@warnings) : join("\n", '', @warnings) ) if $ENV{AUTHOR_TESTING};
t/cmdline-app.t view on Meta::CPAN
use Test::More;
use AI::Pathfinding::OptimizeMultiple::App::CmdLine ();
use vars qw($trap);
eval
q{use Test::Trap qw( trap $trap :flow:stderr(systemsafe):stdout(systemsafe):warn );};
if ($@)
{
plan skip_all => "Test::Trap not found.";
}
plan tests => 6;
my @running_modes = (
{
blurb_base => 'modulino',
sub_ref => sub {
my ($flags) = @_;
AI::Pathfinding::OptimizeMultiple::App::CmdLine->new(
{
argv => [@$flags],
},
)->run();
},
},
{
blurb_base => 'cmd_line',
sub_ref => sub {
my ($flags) = @_;
system( $^X, "bin/optimize-game-ai-multi-tasking", @$flags );
},
},
);
# TEST:$num_subs=2;
foreach my $mode (@running_modes)
{
my $blurb_base = $mode->{blurb_base};
trap( sub { return $mode->{sub_ref}->( [qw(--help)] ); } );
# TEST*$num_subs
like( $trap->stdout(), qr/--output/,
"stdout matches --output flag. ($blurb_base)",
);
# TEST*$num_subs
like(
$trap->stdout(),
qr/--help[^\n]*-h[^\n]*displays this help screen/ms,
"stdout matches --output flag. ($blurb_base)",
);
# TEST*$num_subs
ok( scalar( !$trap->die ), "No exception was thrown. ($blurb_base)", );
}
t/optimize-multiple-full-test.t view on Meta::CPAN
use Test::Differences qw(eq_or_diff);
use PDL (qw/ pdl /);
use AI::Pathfinding::OptimizeMultiple ();
# TEST:$c=0;
sub test_based_on_data
{
local $Test::Builder::Level = $Test::Builder::Level + 1;
my ( $scans_aref, $quotas_aref, $want_results, $stats_factors, $blurb ) =
@_;
my $results_aref = [];
my $selected_scans = [
map {
my $id = $_->{name};
AI::Pathfinding::OptimizeMultiple::Scan->new(
id => $id,
cmd_line => "-l $id",
)
} @{$scans_aref},
];
my %num_boards = ( map { scalar( @{ $_->{data} } ) => 1 } @$scans_aref );
my @nums = keys(%num_boards);
if ( @nums != 1 )
{
Carp::confess("num is not 1.");
}
my $obj = AI::Pathfinding::OptimizeMultiple->new(
{
scans => [ map { +{ name => $_->{name} } } @$scans_aref, ],
num_boards => $nums[0],
scans_iters_pdls =>
{ map { $_->{name} => pdl( $_->{data} ), } @$scans_aref, },
quotas => $quotas_aref,
selected_scans => $selected_scans,
optimize_for => "speed",
( $stats_factors ? ( stats_factors => $stats_factors ) : () ),
}
);
$obj->calc_meta_scan();
my @have = (
map {
+{
name => $scans_aref->[ $_->scan_idx ]->{name},
iters => $_->iters,
}
} @{ $obj->chosen_scans() }
);
# TEST:$c++;
return eq_or_diff( \@have, $want_results, "$blurb - (eq_or_diff)", );
}
# TEST:$test_based_on_data=$c;
{
# TEST*$test_based_on_data
test_based_on_data(
[
{
name => "first",
data => [ 200, 400, 500 ],
},
{
name => "second",
data => [ 300, 50, 1000 ],
},
{
name => "third",
data => [ 10, 10, 100000 ],
},
],
[ 200, 500, ],
[
{
name => "third",
iters => 200,
},
{
name => "first",
iters => 500,
},
],
undef(),
'Basic test',
);
}
{
# TEST*$test_based_on_data
test_based_on_data(
[
{
name => "first",
data => [ 50_000, 100_000, 100_000, 1_000_000, 2_000_000 ],
},
{
name => "second",
data => [ 100, 200, 200, 300, 300 ],
},
{
name => "third",
data => [ 2000, 2000, 2000, 2000, 2000 ],
},
],
[ 100, 300, ],
[
{
name => "first",
iters => 100_000,
},
{
name => "second",
iters => 300,
},
],
{
first => 1000,
},
'Test the stats_factors',
);
}
{
# TEST*$test_based_on_data
test_based_on_data(
[
{
name => "first",
data => [ 50_000, 99_500, 100_000, 1_000_000, 2_000_000 ],
},
{
name => "second",
data => [ 100, 200, 200, 300, 300 ],
},
{
name => "third",
data => [ 2000, 2000, 2000, 2000, 2000 ],
},
],
[ 100, 300, ],
[
{
name => "first",
iters => 100_000,
},
{
name => "second",
iters => 300,
},
],
{
first => 1000,
},
'Test fractional stats due to stats_factors',
);
}
{
# TEST*$test_based_on_data
test_based_on_data(
[
{
name => "first",
data => [ 50_000, 99_500, 100_000, -1, -1, ],
},
{
name => "second",
data => [ 100, 200, 200, 300, 300 ],
},
{
name => "third",
data => [ 2000, 2000, 2000, 2000, 2000 ],
},
],
[ 100, 300, ],
[
{
name => "first",
iters => 100_000,
},
{
name => "second",
iters => 300,
},
],
{
first => 1000,
},
'Test negative stats due to stats_factors',
);
}
t/style-trailing-space.t view on Meta::CPAN
#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
eval "use Test::TrailingSpace";
if ($@)
{
plan skip_all => "Test::TrailingSpace required for trailing space test.";
}
else
{
plan tests => 1;
}
my $finder = Test::TrailingSpace->new(
{
root => '.',
filename_regex =>
qr/(?:(?:\.(?:t|pm|pl|PL|yml|json|arc|vim))|README|Changes|LICENSE)\z/,
},
);
# TEST
$finder->no_trailing_space("No trailing space was found.");
xt/author/eol.t view on Meta::CPAN
use strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::EOL 0.19
use Test::More 0.88;
use Test::EOL;
my @files = (
'bin/optimize-game-ai-multi-tasking',
'lib/AI/Pathfinding/OptimizeMultiple.pm',
'lib/AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm',
'lib/AI/Pathfinding/OptimizeMultiple/DataInputObj.pm',
'lib/AI/Pathfinding/OptimizeMultiple/IterState.pm',
'lib/AI/Pathfinding/OptimizeMultiple/PostProcessor.pm',
'lib/AI/Pathfinding/OptimizeMultiple/Scan.pm',
'lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm',
'lib/AI/Pathfinding/OptimizeMultiple/SimulationResults.pm',
't/00-compile.t',
't/cmdline-app.t',
't/optimize-multiple-full-test.t',
't/style-trailing-space.t'
);
eol_unix_ok($_, { trailing_whitespace => 1 }) foreach @files;
done_testing;
xt/author/no-tabs.t view on Meta::CPAN
use strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::NoTabs 0.15
use Test::More 0.88;
use Test::NoTabs;
my @files = (
'bin/optimize-game-ai-multi-tasking',
'lib/AI/Pathfinding/OptimizeMultiple.pm',
'lib/AI/Pathfinding/OptimizeMultiple/App/CmdLine.pm',
'lib/AI/Pathfinding/OptimizeMultiple/DataInputObj.pm',
'lib/AI/Pathfinding/OptimizeMultiple/IterState.pm',
'lib/AI/Pathfinding/OptimizeMultiple/PostProcessor.pm',
'lib/AI/Pathfinding/OptimizeMultiple/Scan.pm',
'lib/AI/Pathfinding/OptimizeMultiple/ScanRun.pm',
'lib/AI/Pathfinding/OptimizeMultiple/SimulationResults.pm',
't/00-compile.t',
't/cmdline-app.t',
't/optimize-multiple-full-test.t',
't/style-trailing-space.t'
);
notabs_ok($_) foreach @files;
done_testing;
xt/release/cpan-changes.t view on Meta::CPAN
use strict;
use warnings;
# this test was generated with Dist::Zilla::Plugin::Test::CPAN::Changes 0.012
use Test::More 0.96 tests => 1;
use Test::CPAN::Changes;
subtest 'changes_ok' => sub {
changes_file_ok('Changes');
};
xt/release/trailing-space.t view on Meta::CPAN
#!perl
use strict;
use warnings;
use Test::More;
eval "use Test::TrailingSpace";
if ($@)
{
plan skip_all => "Test::TrailingSpace required for trailing space test.";
}
else
{
plan tests => 1;
}
# TODO: add .pod, .PL, the README/Changes/TODO/etc. documents and possibly
# some other stuff.
my $finder = Test::TrailingSpace->new(
{
root => '.',
filename_regex => qr#(?:\.(?:t|pm|pl|xs|c|h|txt|pod|PL)|README|Changes|TODO|LICENSE)\z#,
},
);
# TEST
$finder->no_trailing_space(
"No trailing space was found."
);