某天闲逛时看见一副动图:

    

  真的是非常贪吃,各种拐弯各种吃,感觉十分有趣。

  用Perl来实现自动吃满,蓄谋已久,之前的字符贪吃蛇、深度优先算法、A*算法,都是为此篇做铺垫。

  

  那么,怎样让蛇不吃到自己呢?

  1、让蛇按照我们设计好的路线行进,在一个N*M(N、M均为偶数,奇数不讨论)的游戏区域,设计好路线如下:

    

    当花儿谢了,果子熟透,春夏秋冬一个轮回后,蛇终于吃满了。。。

  2、假设蛇总是追着自己的尾巴跑,那么永远不会死;然而,这没什么鸟用,我们需要的是一条“贪吃”的蛇。

  3、在2上稍稍改进,吃完食物后再追着尾巴,嗯,已经很接近了。但是问题来了:怎么吃到食物?吃到食物后被围死怎么办?

  其实我的想法就是解决3中的问题:

  1、使用A*算法计算到食物的最短路径

  2、模拟吃到食物后的场景,能否回到蛇尾;能--吃食物,不能--继续追着尾巴,重复1、2

  3、如果无法回到尾巴,保持当前移动方向(认命吧,要挂的节奏)

  伪码如下:

#    while( 存活 && 未吃满){
# 计算蛇头到食物的路径
# if( 有蛇头到食物的路径 ){
# 模拟吃到食物后的场景
# 计算是否有路径到达蛇尾
# if( 有路径 ){
# 执行蛇头到食物的路径
# }
# else{ # 没有到蛇尾的路径
# next
# }
# }
# 找出当前可行方向追逐蛇尾
# }
# if(吃满){
# 显示:祝贺
# }
# else{
# 显示:wtf ?
# }

  模拟吃到食物后的场景:使用A*计算路径,并创建一条“影子蛇”用来模拟吃到食物后的状态

  计算是否有路径到达蛇尾:和“追逐蛇尾”方法类似,也可使用A*

  找出当前可行方向追逐蛇尾:

    由于移动时尾巴会变动,未尝试A*,使用指定方向深度优先搜索算法

    伪码如下:

sub trace_tail{
@moves=grep{可行};
foreach(@moves){
next if(下一步越界 || 吃到自己)
unshift @feasible,$_ if(远离食物)
其他方向 push @feasible
}
foreach(@feasible){
next_move=cur_move+$_
指定方向优先探索
next_move的反向上一步设为不可通过
每走一步,从蛇尾开始设未经过;每原路返回一次,当前位置的蛇身设不可通过
if(有路径)return next_move
}
执行完毕无路径,return cur_move
}

  

  运行如下:

    

  实际上还是会被困死,虽然追逐尾巴时避开食物优先,但唯一路径可能会出现食物,不吃也得吃了,如下:

    

  代码较乱,准备加好注释后贴上来。

  有很大的优化空间,等有时间再慢慢搞,代码:

use strict;
use 5.01;
use Time::HiRes qw/sleep/;
use Term::ReadKey;
use constant {WIDTH=>,HEIGHT=>,DEBUG=>};
my @bg=();
my @snake=();
my @head2food=();
my @food_coordinate=(); # 保存食物坐标
my ($score,$food,$speed,$alive,$head2tail,$head_move)=(,,,,,); # 得分、食物、速度、存活、能否回到尾巴的标志、初始移动方向
my $full=(WIDTH-)*(HEIGHT-);
my %opposite=( =>,
=>,
=>,
=>, ); # 对立的移动方向,禁止反向移动
my @uldr=( ,[-,],[,-],[,],[,], ); # 上、左、下、右
############################################################################################
&init;
#my $move=&manual_move(4); # 开始向右移动
my $move=&smart_move($head_move);$speed=;
while( $alive && @snake < $full ){
@head2food=&head_to_food($head_move,@snake); # 计算蛇头到食物的路径
if( $head2food[] != ){ # 有路径
$head2tail=&head_to_tail(\@snake,\@head2food); # 判断吃到食物后是否能回到尾巴
if($head2tail){ # 能回到尾巴,吃食物
foreach( @head2food ){
$head_move=$_;
$move->($head_move);
&check_head;
if($alive){
&show;
sleep (-$speed*0.1);
}
}
}
}
$head_move=&trace_tail($head_move,@snake); # 找出当前可行方向追逐蛇尾
$move->($head_move);
&check_head;
if($alive){
&show;
sleep (-$speed*0.1);
}
}
if(@snake==$full){
print "\ncongratulations!\n"; # 蛇占满游戏区时显示
}
else{
print "\nWTF?\n";
}
############################################################################################
sub init{
my $y=int(HEIGHT/);
for(my $y=;$y<HEIGHT;$y++){
for( my $x= ; $x<WIDTH ; $x++ ){
if( $y == || $y == HEIGHT- ||
$x == || $x == WIDTH- ){
$bg[$y][$x] = '*';
}
else{
$bg[$y][$x] = ' ';
}
}
}
@{$bg[$y]}[,]=('#','@'); # 初始蛇身位置
@snake=( [$y,],[$y,], ); # 保存蛇身坐标
&make_food; # 产生食物
}
############################################################################################
sub show{
system("cls") unless(DEBUG);
print "your score : $score\n";
print "current speed : ",$speed,"\n\n";
print @$_,"\n" foreach(@bg);
}
############################################################################################
sub smart_move{
my $move_direct=shift;
sub{ # 闭包,传入初始移动方向
$move_direct=shift;
unshift @snake,[$snake[][]+$uldr[$move_direct][],$snake[][]+$uldr[$move_direct][]];
}
}
############################################################################################
sub head_to_food{ # 蛇头到食物
my $head_shadow=shift;
my @snake_ghost=@_;
my @bg_ghost=@bg;
my @path=&a_star( [ $snake_ghost[][],$snake_ghost[][] ],
[ $food_coordinate[],$food_coordinate[] ],\@bg_ghost ); # A*算法,传递起点、终点、蛇当前坐标指针
return @path;
}
############################################################################################
# 追逐尾巴,传递当前移动方向、蛇身所有坐标
sub trace_tail{
print "call trace_tail\n" if DEBUG;
my $cur_move=shift; # 当前移动方向
my @snake_ghost=@_;
my @path=();
my $cur_position=[ $snake_ghost[][],$snake_ghost[][] ]; # 起点
print " cur_position:",$snake_ghost[][],",",$snake_ghost[][],"\n" if DEBUG;
my $end=[ $snake_ghost[-][],$snake_ghost[-][] ]; # 终点
my $tail=$#snake_ghost; # 蛇长度 my @bg_ghost=map{ [ split('','0'x WIDTH) ] }..(HEIGHT-); # 0--未经过 1--已走 2--不可通过
map{ my $y=$_;map { $bg_ghost[$y][$_] = ( $bg[$y][$_] eq '*' )?: }..$#{$bg[0]} }0..$#bg;
map{ $bg_ghost[ $snake_ghost[$_][] ][ $snake_ghost[$_][] ] = } ..$#snake_ghost; # 蛇身不可通过
my @feasible=();
my @next_moves=grep{ ! /$opposite{$cur_move}/ }values %opposite; # 取出除反方向的可行方向
my $weight=;
foreach(@next_moves){
$weight=;
my $next_move=$_;
my ($y,$x)=( $snake_ghost[][]+$uldr[$next_move][],$snake_ghost[][]+$uldr[$next_move][] );
# 防止越界
if( $y < || $y > HEIGHT- || $x < || $x > WIDTH-){
$weight=;
next;
} # 防止吃到自己
foreach(..$#snake_ghost){
if( $y == $snake_ghost[$_][] && $x == $snake_ghost[$_][] ){
$weight=;
last;
}
}
if($weight){
if( abs($y - $food_coordinate[]) > abs($snake_ghost[][] - $food_coordinate[]) ||
abs($x - $food_coordinate[]) > abs($snake_ghost[][] - $food_coordinate[]) ){
unshift @feasible,$next_move; # 远离食物放到数组头
}
else{
push @feasible,$next_move; # 其他路径放在末尾
}
}
}
print " feasible:@feasible\n" if DEBUG;
foreach(@feasible){
@path=();
$cur_move=$_;
print " cur_move:$cur_move\n" if DEBUG;
my @one234 = (); # 将当前移动方向设置为初始方向
given($cur_move){
when(){ @one234 = @uldr;}
when(){ @one234 = @uldr[,,,,]; }
when(){ @one234 = @uldr[,,,,]; }
when(){ @one234 = @uldr[,,,,]; }
}
#################################################################
# 指定方向深度搜索
my ($step,$p_step)=(,'');
do{
if($bg_ghost[ $cur_position->[] ][ $cur_position->[] ] == ){
$bg_ghost[ $cur_position->[] ][ $cur_position->[] ]=;
# 当前移动方向的反方向点不可经过,即禁止回退
$bg_ghost[ $snake_ghost[][]+$uldr[$opposite{$cur_move}]->[] ][ $snake_ghost[][]+$uldr[$opposite{$cur_move}]->[] ] = ;
$bg_ghost[ $snake_ghost[][] ][ $snake_ghost[][] ] = ; # 当前点不可返回
if( $cur_position->[] == $food_coordinate[] && $cur_position->[] == $food_coordinate[] ){
push @snake_ghost,[ $snake_ghost[-][],$snake_ghost[-][] ];
}
$path[$step]={step=>$step,
coordinate=>[$cur_position->[],$cur_position->[]],
direct=>,
};
$path[$step]->{direct}= if($step == ); # 起点不可再做起点
print " path[$step]:$path[$step]:",$path[$step]->{step},"\n" if DEBUG;
if(DEBUG){
print @$_,"\n" foreach(@bg_ghost);
}
if( $cur_position->[]==$end->[] && $cur_position->[]==$end->[]){
my @arr=('A'..'Z','a'..'z');
foreach(..$#path){
$bg_ghost[ $path[$_]->{coordinate}->[] ][ $path[$_]->{coordinate}->[] ] = $arr[$_];
}
print " trace_tail: return $cur_move\n" if DEBUG;
return $cur_move; # 有可行方向,返回
}
$step++;
if($step> && $step<=$#snake_ghost){
$bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] =
if ( $bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] == ); # 每移动一次,将蛇尾所在坐标设未经过
$tail=($tail>)?($tail-):;
}
$cur_position=[ $path[$step-]->{coordinate}->[]+$one234[]->[],
$path[$step-]->{coordinate}->[]+$one234[]->[] ];
print " (y,x):(",$cur_position->[],",",$cur_position->[],")\n" if DEBUG;
}
else{
if(@path){
$p_step=pop(@path);
while($p_step->{direct}== && (@path)){
$bg_ghost[ $p_step->{coordinate}->[] ][ $p_step->{coordinate}->[] ] = ;
$p_step=pop(@path);
$step--; $tail=($tail<$#snake_ghost-1)?($tail+1):$#snake_ghost-1;
$bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] =
if ( $bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] == ); # 每回退一次,将蛇尾所在坐标设为不可通过 }
if($p_step->{direct}<){
$p_step->{direct}++;
print " ",$p_step->{step},":p_step->{direct}:",$p_step->{direct},"\n" if DEBUG;
push @path,$p_step;
my @temp=@{$p_step->{coordinate}}[,];
$cur_position = [ $temp[]+$one234[$p_step->{direct}]->[],
$temp[]+$one234[$p_step->{direct}]->[] ];
print " (y,x):(",$cur_position->[],",",$cur_position->[],")\n" if DEBUG;
}
}
}
}while(@path);
# 指定方向深度搜索结束
#################################################################
}
print " cur_move:$cur_move trace_tail:return fail\n" if DEBUG;
return $cur_move; # 没有到尾巴的可行方向了,准备认命
}
#######################################################################################
# 能否到尾巴位置,能返回1,否则返回0
# 算法大致与 trace_tail 相同
sub head_to_tail{
print "call head_to_tail\n" if DEBUG;
my ($p_snake,$p_path)=@_;
my @snake_ghost=@$p_snake;
my @path=@$p_path;
my $cur_move=$path[-];
my @arr=();
foreach(..$#path){
my ($y,$x)=( $snake_ghost[][]+$uldr[ $path[$_] ]->[],$snake_ghost[][]+$uldr[ $path[$_] ]->[] );
unshift @snake_ghost,[$y,$x];
pop @snake_ghost if($_ < $#path);
} # 影子蛇先行,吃到食物后的状态
@path=();
my $cur_position=[ $snake_ghost[][],$snake_ghost[][] ];
print " cur_position:",$snake_ghost[][],",",$snake_ghost[][],"\n" if DEBUG;
my $end=[ $snake_ghost[-][],$snake_ghost[-][] ];
my $tail=$#snake_ghost; my @bg_ghost=map{ [ split('','0'x WIDTH) ] }..(HEIGHT-); # 0--未经过 1--已走 2--不可通过
map{ my $y=$_;map { $bg_ghost[$y][$_] = ( $bg[$y][$_] eq '*' )?: }..$#{$bg[0]} }0..$#bg;
map{ $bg_ghost[ $snake_ghost[$_][] ][ $snake_ghost[$_][] ] = } ..$#snake_ghost; # 蛇身不可通过
my @feasible=();
my @next_moves=grep{ ! /$opposite{$cur_move}/ }values %opposite;
my $weight=;
foreach(@next_moves){
$weight=;
my $next_move=$_;
my ($y,$x)=( $snake_ghost[][]+$uldr[$next_move][],$snake_ghost[][]+$uldr[$next_move][] );
# 防止越界
if( $y < || $y > HEIGHT- || $x < || $x > WIDTH-){
$weight=;
next;
} # 防止吃到自己
foreach(..$#snake_ghost){
if( $y == $snake_ghost[$_][] && $x == $snake_ghost[$_][] ){
$weight=;
last;
}
}
if($weight){
push @feasible,$next_move; # 路径随意放
}
}
print " feasible:@feasible\n" if DEBUG;
foreach(@feasible){
@path=();
$cur_move=$_;
my @one234 = (); # 将当前移动方向设置为初始方向
given($cur_move){
when(){ @one234 = @uldr;}
when(){ @one234 = @uldr[,,,,]; }
when(){ @one234 = @uldr[,,,,]; }
when(){ @one234 = @uldr[,,,,]; }
}
#################################################################
# 指定方向深度搜索
my ($step,$p_step)=(,'');
do{
if($bg_ghost[ $cur_position->[] ][ $cur_position->[] ] == ){
$bg_ghost[ $cur_position->[] ][ $cur_position->[] ]=;
$bg_ghost[ $snake_ghost[][]+$uldr[$opposite{$cur_move}]->[] ][ $snake_ghost[][]+$uldr[$opposite{$cur_move}]->[] ] = ;
$bg_ghost[ $snake_ghost[][] ][ $snake_ghost[][] ] = ; # 当前点不可返回
$path[$step]={step=>$step,
coordinate=>[$cur_position->[],$cur_position->[]],
direct=>,
};
$path[$step]->{direct}= if($step == ); # 起点不可再做起点
print " path[$step]:$path[$step]:",$path[$step]->{step},"\n" if DEBUG;
if( $cur_position->[]==$end->[] && $cur_position->[]==$end->[]){
my @arr=('A'..'Z','a'..'z');
foreach(..$#path){
$bg_ghost[ $path[$_]->{coordinate}->[] ][ $path[$_]->{coordinate}->[] ] = $arr[$_];
}
print " head_to_tail: return 1\n" if DEBUG;
return ;
}
$step++;
if($step> && $step<=$#snake_ghost){
$bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] =
if ( $bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] == ); # 每移动一次,将蛇尾所在坐标设未经过
$tail=($tail>)?($tail-):;
}
$cur_position=[ $path[$step-]->{coordinate}->[]+$one234[]->[],
$path[$step-]->{coordinate}->[]+$one234[]->[] ];
print " (y,x):(",$cur_position->[],",",$cur_position->[],")\n" if DEBUG;
}
else{
if(@path){
$p_step=pop(@path);
while($p_step->{direct}== && (@path)){
$bg_ghost[ $p_step->{coordinate}->[] ][ $p_step->{coordinate}->[] ] = ;
$p_step=pop(@path);
$step--;
$tail=($tail<$#snake_ghost)?($tail+1):$#snake_ghost;
$bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] =
if ( $bg_ghost[ $snake_ghost[$tail][] ][ $snake_ghost[$tail][] ] == ); # 每回退一次,将蛇尾所在坐标设为不可通过
if(DEBUG){
print @$_,"\n" foreach(@bg_ghost);
}
}
if($p_step->{direct}<){
$p_step->{direct}++;
print " ",$p_step->{step},":p_step->{direct}:",$p_step->{direct},"\n" if DEBUG;
push @path,$p_step;
my @temp=@{$p_step->{coordinate}}[,];
$cur_position = [ $temp[]+$one234[$p_step->{direct}]->[],
$temp[]+$one234[$p_step->{direct}]->[] ];
print " (y,x):(",$cur_position->[],",",$cur_position->[],")\n" if DEBUG;
}
}
}
}while(@path);
# 指定方向深度搜索结束
#################################################################
}
print " head_to_tail:return 0\n" if DEBUG;
return ;
}
#######################################################################################
sub caclulate_cost{
my ($sp,$ep)=@_;
return abs($sp->[] - $ep->[]) + abs($sp->[] - $ep->[]);
}
#######################################################################################
# A*算法
sub a_star{
print "call a_star\n" if DEBUG;
my $start=shift; # 起点
my $end=shift; # 终点
my $p_arr=shift;
my @bg_ghost=@{$p_arr}; my @path=(); # 存放步数的数组
my @open_close=();
my ($step,$p_step,$p_gh)=(,'',''); # 步数、指向数组元素的指针、指向open_close元素的指针
map{ my $y=$_;map { $open_close[$y][$_]->{flag} = ( $bg_ghost[$y][$_] eq '#' || $bg_ghost[$y][$_] eq '*')?: }..$#{$bg_ghost[0]} }0..$#bg; # 障碍物设置不可通过 $path[$step]={ coordinate=>[$start->[],$start->[]],
cost=>,
next_cost=>&caclulate_cost( $start,$end ),
previous=>,
};
$path[$step]->{actual_cost}=$path[$step]->{cost} + $path[$step]->{next_cost};
$open_close[ $start->[] ][ $start->[] ]->{point}='';
while(@path){
$p_step=pop(@path);
print " step:$step,p_step:$p_step\n" if DEBUG;
if( $p_step->{coordinate}->[] == $end->[] &&
$p_step->{coordinate}->[] == $end->[] ){
my @arr=();
my @temp=();
while($p_step){
push @temp,$p_step->{coordinate};
$p_step=$p_step->{previous};
}
@temp=reverse(@temp);
foreach(..$#temp-1){
my $line=($temp[$_+][]-$temp[$_][])."a".($temp[$_+][]-$temp[$_][]);
given($line){
when('-1a0'){ push @arr, ;}
when('0a-1'){ push @arr, ;}
when('1a0') { push @arr, ;}
when('0a1') { push @arr, ;}
} # 从父节点回溯,获取每一步移动方向
}
return @arr;
}
$step++;
for(my $cnt=;$cnt<=;$cnt++){
my $y= $p_step->{coordinate}->[]+$uldr[$cnt][] ;
my $x= $p_step->{coordinate}->[]+$uldr[$cnt][] ;
print " ($p_step->{coordinate}->[0],$p_step->{coordinate}->[1])+($uldr[$cnt][0],$uldr[$cnt][1]),(y,x)=($y,$x)\n" if DEBUG;
next if( $open_close[$y][$x]->{flag} == ||
$y < || $y > HEIGHT- || $x < || $x > WIDTH- ); if( $open_close[$y][$x]->{flag} == ){
$open_close[$y][$x]->{flag}=;
$open_close[$y][$x]->{point}=$p_step;
my $px={ coordinate=>[$y,$x],
cost=>$p_step->{cost}+,
next_cost=>&caclulate_cost( [$y,$x],$end ),
previous=>$p_step,
};
$px->{actual_cost}=$px->{cost} + $px->{next_cost};
push @path,$px;
}
else{
$p_gh=$open_close[$y][$x]->{point};
print " p_gh:$p_gh\n" if DEBUG;
if($p_gh && $p_step->{cost}+ < $p_gh->{cost} ){
print " $p_step->{cost},$p_gh->{cost}\n" if DEBUG;
$p_gh->{cost}=$p_step->{cost}+;
$p_gh->{previous}=$p_step;
$p_gh->{actual_cost}=$p_gh->{cost}+$p_gh->{next_cost};
}
}
}
$open_close[ $p_step->{coordinate}->[] ][ $p_step->{coordinate}->[] ]->{flag}=;
@path=sort{$b->{actual_cost}<=>$a->{actual_cost}}@path;
}
print " a_star: return 0\n" if DEBUG;
return ;
}
#######################################################################################
sub manual_move{
# 闭包,为了传入初始移动方向
my $move_direct=shift;
sub{
ReadMode ;
my $key=ReadKey(-);
$key=~tr/a-z/A-Z/ if $key;
given($key){
# 不允许反向移动
when('W'){ $move_direct = ( == $move_direct )? : ; }
when('A'){ $move_direct = ( == $move_direct )? : ; }
when('S'){ $move_direct = ( == $move_direct )? : ; }
when('D'){ $move_direct = ( == $move_direct )? : ; }
default { $move_direct; }
}
unshift @snake,[$snake[][]+$uldr[$move_direct][],$snake[][]+$uldr[$move_direct][]];
}
}
#######################################################################################
sub make_food{
if(@snake < $full){
my @empty_points=();
foreach(..$#bg-1){
my $y=$_;
foreach(..$#{$bg[0]}-1){
push @empty_points,[$y,$_] if($bg[$y][$_] eq ' ');
}
} # 找出所有空的坐标点,存入@empty_points数组
my $num=int( rand( scalar(@empty_points) ) ); # 随机取出@empty_points下标
my ($y,$x)=@{ $empty_points[$num] }[,];
$bg[$y][$x]='O';
@food_coordinate=($y,$x);
$food=;
}
}
#######################################################################################
sub check_head{
# 蛇身超出范围
if($snake[][] < || $snake[][] > HEIGHT- ||
$snake[][] < || $snake[][] > WIDTH- ){
$alive=;
}
# 蛇吃到自己
if(@snake>){
foreach(..$#snake){
if($snake[][] == $snake[$_][] && $snake[][] == $snake[$_][]){
$alive=;
}
}
}
# 移动
if($bg[$snake[][]][$snake[][]] eq ' '){
$bg[$snake[][]][$snake[][]]='@';
}
# 吃到食物
if($bg[$snake[][]][$snake[][]] eq 'O'){
$bg[$snake[][]][$snake[][]]='@';
$score++;
$food=;
&make_food;
push @snake,[$snake[-][],$snake[-][]]; # 新的蛇身放在尾部
}
$bg[$snake[-][]][$snake[-][]]=' '; # 先清除尾巴显示
pop @snake; # 去掉尾巴
map{$bg[$snake[$_][]][$snake[$_][]]='#'}..$#snake; # 其他蛇身显示
}

  

Perl看完这个,再不敢说自己会玩贪吃蛇的更多相关文章

  1. 看完SQL Server 2014 Q/A答疑集锦:想不升级都难!

    看完SQL Server 2014 Q/A答疑集锦:想不升级都难! 转载自:http://mp.weixin.qq.com/s/5rZCgnMKmJqeC7hbe4CZ_g 本期嘉宾为微软技术中心技术 ...

  2. 在知乎上看到 Web Socket这篇文章讲得确实挺好,从头看到尾都非常形象生动,一口气看完,没有半点模糊,非常不错

    在知乎上看到这篇文章讲得确实挺好,从头看到尾都非常形象生动,一口气看完,没有半点模糊,非常不错,所以推荐给大家,非常值得一读. 作者:Ovear链接:https://www.zhihu.com/que ...

  3. 盘点国内程序员不常用的热门iOS第三方库:看完,还敢自称”精通iOS开发”吗?【转载】

    综合github上各个项目的关注度与具体使用情况,涵盖功能,UI,数据库,自动化测试,编程工具等类型,看完,还敢自称”精通iOS开发”吗? https://github.com/syedhali/EZ ...

  4. APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了

    APP的缓存文件到底应该存在哪?看完这篇文章你应该就自己清楚了 彻底理解android中的内部存储与外部存储 存储在内部还是外部 所有的Android设备均有两个文件存储区域:"intern ...

  5. 视频1-14待JSP课程看完再练习

    视频1-14待JSP课程看完再练习 http://www.imooc.com/video/5555

  6. 看完这些,你就算得上既了解围棋又了解alphago了

    首先,我们要祝贺小李下出第78手的“神之一手”,这一手堪称前无古人后无来者,尤其是结合了阿尔法狗自暴自弃的表现.小李说过他的失败并不是人类的失败,同样,小李的胜利也只是属于他一人的胜利. 然而人类在围 ...

  7. 看完final的感受

    今天没课,(其实是有体育课的,去打了一会球就跑路了...)就在宿舍看world final ; 我去,老毛子真是好厉害,看的我目瞪口呆,哈喇子直流; 上交的大神好厉害,本来还以为上交要夺冠的,最后罚时 ...

  8. Servlet 是否线程安全 看完便知

    Servlet 是否线程安全 看完便知 转自:http://blog.sina.com.cn/s/blog_6448959f0100kct7.html     摘 要:介绍了Servlet多线程机制, ...

  9. Windows PowerShell是啥?看完本文你就懂它了

    这篇文章主要介绍了Windows PowerShell是啥?Windows PowerShell是什么?Windows PowerShell有哪些特性?Windows PowerShell有什么用?看 ...

随机推荐

  1. LAMP环境搭建之编译安装指南(php-5.3.27.tar.gz)

    测试环境:CentOS release 6.5 (Final) 软件安装:httpd-2.2.27.tar.gz   mysql-5.1.72.tar.gz   php-5.3.27.tar.gz 1 ...

  2. Python——模块合集

    标准库模块 ● Python——OS(系统操作模块) ● Python——MD5(加密模块) ● Python——time(时间模块) ● Python——re(正则表达式) ● Python——sy ...

  3. Kubernetes-Istio之Sidecar自动注入

    前提: (官方提供) 1):确认使用的是Kubernetes服务器的受支持版本( 1.13.1.14.1.15):kubectl (官方提供,应该是1.13版本以上,我的是1.16版本) kubect ...

  4. Makefile学习二

    今天继续对Makefile进行研究,话不多说,进入正题: make常用内嵌函数: 下面利用上面的知识点来实现一个多级目录的Makefile,如下: 多级目录Makefile: 这个例子的目录结构如下: ...

  5. django-ContentType的简单使用

    ContentType 一般我们有多张表同时外键关联同一张表的时候,可以考虑使用ContentType models.py from django.db import models from djan ...

  6. 零基础如何学好Python 之int 数字整型类型 定义int()范围大小转换

    本文主题是讲python数字类型python int整型使用方法及技巧.它是不可变数据类型中的一种,它的一些性质和字符串是一样的,注意是整型不是整形哦. Python int有多种数字类型:整型int ...

  7. 《基于 Java EE 的高校重修管理系统设计与实现》论文笔记(九)

    标题:基于 Java EE 的高校重修管理系统设计与实现 一.基本信息 时间:2015 来源:河海大学文天学院 关键词::Java EE 架构: B/S 模式: 重修管理系统 二.研究内容 1.需求分 ...

  8. service worker(一)之离线应用

    serviceWork.html <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  9. Linux PXE 网络装机

    一.基础网络建设 Linux配置静态IP-192.168.5.1 # vim /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 ONBOOT= ...

  10. 洛谷 P816 忠诚 题解

    每日一题 day28 打卡 Analysis 这道题用线段树维护区间最小值很简单,因为没有修改所以连lazy_tag都不用,但是这道题可以用树状数组维护区间最小值,非常骚气. 线段树代码: #incl ...