我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python游戏实战项目之智能五子棋

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python游戏实战项目之智能五子棋

导语

图片

今日游戏更新,大家好,我是木木子,每天都给大家更新最好玩的游戏!关注我,从此你再也不用去费力找游戏了!

最热门最好玩的Python游戏点击即玩!

今天推荐的游戏是五子棋小游戏——人机对战、联机对战皆可!

你是否还记得?中学时代和同桌下过的五子棋?

图片

这样下棋只怕是会被打!​!!!我怀疑他开挂了,并且找到了证据。

图片

正文

首先准备好需要的图片等素材部分如下:

​​

好了!直接上代码吧——设置游戏开始界面:


class gameStartUI(QWidget):
    def __init__(self, parent=None, **kwargs):
        super(gameStartUI, self).__init__(parent)
        self.setFixedSize(760, 650)
        self.setWindowTitle('五子棋游戏对战')
        self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
        # 背景图片
        palette = QPalette()
        palette.setBrush(self.backgroundRole(), QBrush(QPixmap(cfg.BACKGROUND_IMAGEPATHS.get('bg_start'))))
        self.setPalette(palette)
        # 按钮
        # --人机对战
        self.ai_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('ai'), self)
        self.ai_button.move(250, 200)
        self.ai_button.show()
        self.ai_button.click_signal.connect(self.playWithAI)
        # --联机对战
        self.online_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('online'), self)
        self.online_button.move(250, 350)
        self.online_button.show()
        self.online_button.click_signal.connect(self.playOnline)
    '''人机对战'''
    def playWithAI(self):
        self.close()
        self.gaming_ui = playWithAIUI(cfg)
        self.gaming_ui.exit_signal.connect(lambda: sys.exit())
        self.gaming_ui.back_signal.connect(self.show)
        self.gaming_ui.show()
    '''联机对战'''
    def playOnline(self):
        self.close()
        self.gaming_ui = playOnlineUI(cfg, self)
        self.gaming_ui.show()
 
 
'''run'''
if __name__ == '__main__':
    app = QApplication(sys.argv)
    handle = gameStartUI()
    font = QFont()
    font.setPointSize(12)
    handle.setFont(font)
    handle.show()
    sys.exit(app.exec_())

效果如下:

​​

一个是五子棋规则设置的人机对战:


import pygame
from ..misc import *
from PyQt5 import QtCore
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from itertools import product
from .aiGobang import aiGobang
 
 
'''人机对战'''
class playWithAIUI(QWidget):
    back_signal = pyqtSignal()
    exit_signal = pyqtSignal()
    send_back_signal = False
    def __init__(self, cfg, parent=None, **kwargs):
        super(playWithAIUI, self).__init__(parent)
        self.cfg = cfg
        self.setFixedSize(760, 650)
        self.setWindowTitle('五子棋人机对战')
        self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
        # 背景图片
        palette = QPalette()
        palette.setBrush(self.backgroundRole(), QBrush(QPixmap(cfg.BACKGROUND_IMAGEPATHS.get('bg_game'))))
        self.setPalette(palette)
        # 按钮
        self.home_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('home'), self)
        self.home_button.click_signal.connect(self.goHome)
        self.home_button.move(680, 10)
        self.startgame_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('startgame'), self)
        self.startgame_button.click_signal.connect(self.startgame)
        self.startgame_button.move(640, 240)
        self.regret_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('regret'), self)
        self.regret_button.click_signal.connect(self.regret)
        self.regret_button.move(640, 310)
        self.givein_button = PushButton(cfg.BUTTON_IMAGEPATHS.get('givein'), self)
        self.givein_button.click_signal.connect(self.givein)
        self.givein_button.move(640, 380)
        # 落子标志
        self.chessman_sign = QLabel(self)
        sign = QPixmap(cfg.CHESSMAN_IMAGEPATHS.get('sign'))
        self.chessman_sign.setPixmap(sign)
        self.chessman_sign.setFixedSize(sign.size())
        self.chessman_sign.show()
        self.chessman_sign.hide()
        # 棋盘(19*19矩阵)
        self.chessboard = [[None for i in range(19)] for _ in range(19)]
        # 历史记录(悔棋用)
        self.history_record = []
        # 是否在游戏中
        self.is_gaming = True
        # 胜利方
        self.winner = None
        self.winner_info_label = None
        # 颜色分配and目前轮到谁落子
        self.player_color = 'white'
        self.ai_color = 'black'
        self.whoseround = self.player_color
        # 实例化ai
        self.ai_player = aiGobang(self.ai_color, self.player_color)
        # 落子声音加载
        pygame.mixer.init()
        self.drop_sound = pygame.mixer.Sound(cfg.SOUNDS_PATHS.get('drop'))
    '''鼠标左键点击事件-玩家回合'''
    def mousePressEvent(self, event):
        if (event.buttons() != QtCore.Qt.LeftButton) or (self.winner is not None) or (self.whoseround != self.player_color) or (not self.is_gaming):
            return
        # 保证只在棋盘范围内响应
        if event.x() >= 50 and event.x() <= 50 + 30 * 18 + 14 and event.y() >= 50 and event.y() <= 50 + 30 * 18 + 14:
            pos = Pixel2Chesspos(event)
            # 保证落子的地方本来没有人落子
            if self.chessboard[pos[0]][pos[1]]:
                return
            # 实例化一个棋子并显示
            c = Chessman(self.cfg.CHESSMAN_IMAGEPATHS.get(self.whoseround), self)
            c.move(event.pos())
            c.show()
            self.chessboard[pos[0]][pos[1]] = c
            # 落子声音响起
            self.drop_sound.play()
            # 最后落子位置标志对落子位置进行跟随
            self.chessman_sign.show()
            self.chessman_sign.move(c.pos())
            self.chessman_sign.raise_()
            # 记录这次落子
            self.history_record.append([*pos, self.whoseround])
            # 是否胜利了
            self.winner = checkWin(self.chessboard)
            if self.winner:
                self.showGameEndInfo()
                return
            # 切换回合方(其实就是改颜色)
            self.nextRound()
    '''鼠标左键释放操作-调用电脑回合'''
    def mouseReleaseEvent(self, event):
        if (self.winner is not None) or (self.whoseround != self.ai_color) or (not self.is_gaming):
            return
        self.aiAct()
    '''电脑自动下-AI回合'''
    def aiAct(self):
        if (self.winner is not None) or (self.whoseround == self.player_color) or (not self.is_gaming):
            return
        next_pos = self.ai_player.act(self.history_record)
        # 实例化一个棋子并显示
        c = Chessman(self.cfg.CHESSMAN_IMAGEPATHS.get(self.whoseround), self)
        c.move(QPoint(*Chesspos2Pixel(next_pos)))
        c.show()
        self.chessboard[next_pos[0]][next_pos[1]] = c
        # 落子声音响起
        self.drop_sound.play()
        # 最后落子位置标志对落子位置进行跟随
        self.chessman_sign.show()
        self.chessman_sign.move(c.pos())
        self.chessman_sign.raise_()
        # 记录这次落子
        self.history_record.append([*next_pos, self.whoseround])
        # 是否胜利了
        self.winner = checkWin(self.chessboard)
        if self.winner:
            self.showGameEndInfo()
            return
        # 切换回合方(其实就是改颜色)
        self.nextRound()
    '''改变落子方'''
    def nextRound(self):
        self.whoseround = self.player_color if self.whoseround == self.ai_color else self.ai_color
    '''显示游戏结束结果'''
    def showGameEndInfo(self):
        self.is_gaming = False
        info_img = QPixmap(self.cfg.WIN_IMAGEPATHS.get(self.winner))
        self.winner_info_label = QLabel(self)
        self.winner_info_label.setPixmap(info_img)
        self.winner_info_label.resize(info_img.size())
        self.winner_info_label.move(50, 50)
        self.winner_info_label.show()
    '''认输'''
    def givein(self):
        if self.is_gaming and (self.winner is None) and (self.whoseround == self.player_color):
            self.winner = self.ai_color
            self.showGameEndInfo()
    '''悔棋-只有我方回合的时候可以悔棋'''
    def regret(self):
        if (self.winner is not None) or (len(self.history_record) == 0) or (not self.is_gaming) and (self.whoseround != self.player_color):
            return
        for _ in range(2):
            pre_round = self.history_record.pop(-1)
            self.chessboard[pre_round[0]][pre_round[1]].close()
            self.chessboard[pre_round[0]][pre_round[1]] = None
        self.chessman_sign.hide()
    '''开始游戏-之前的对弈必须已经结束才行'''
    def startgame(self):
        if self.is_gaming:
            return
        self.is_gaming = True
        self.whoseround = self.player_color
        for i, j in product(range(19), range(19)):
            if self.chessboard[i][j]:
                self.chessboard[i][j].close()
                self.chessboard[i][j] = None
        self.winner = None
        self.winner_info_label.close()
        self.winner_info_label = None
        self.history_record.clear()
        self.chessman_sign.hide()
    '''关闭窗口事件'''
    def closeEvent(self, event):
        if not self.send_back_signal:
            self.exit_signal.emit()
    '''返回游戏主页面'''
    def goHome(self):
        self.send_back_signal = True
        self.close()
        self.back_signal.emit()

如下:害!我这下了很久呢,有几次都没下赢人机!2333游戏废材

图片

​​

另一个定义联机对战:


import sys
import random
from .server import *
from .client import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
 
 
'''联机对战'''
class playOnlineUI(QWidget):
    def __init__(self, cfg, home_ui, parent=None, **kwargs):
        super(playOnlineUI, self).__init__(parent)
        self.cfg = cfg
        self.home_ui = home_ui
        self.setWindowTitle('联机对战')
        self.setWindowIcon(QIcon(cfg.ICON_FILEPATH))
        self.setFixedSize(300, 200)
        # 昵称
        self.nickname = random.choice(['杰尼龟', '皮卡丘', '小火龙', '小锯鳄', '妙蛙种子', '菊草叶'])
        self.layout0 = QHBoxLayout()
        self.nickname_label = QLabel('游戏昵称:', self)
        self.nickname_edit = QLineEdit(self)
        self.nickname_edit.setText(self.nickname)
        self.layout0.addWidget(self.nickname_label, 1)
        self.layout0.addWidget(self.nickname_edit, 3)
        # IP
        self.target_ip = '127.0.0.1'
        self.layout1 = QHBoxLayout()
        self.ip_label = QLabel('对方IP:', self)
        self.ip_edit = QLineEdit(self)
        self.ip_edit.setText(self.target_ip)
        self.layout1.addWidget(self.ip_label, 1)
        self.layout1.addWidget(self.ip_edit, 3)
        # 按钮
        self.layout2 = QHBoxLayout()
        self.connect_button = QPushButton('作为客户端', self)
        self.connect_button.clicked.connect(self.becomeClient)
        self.ashost_button = QPushButton('作为服务器', self)
        self.ashost_button.clicked.connect(self.becomeHost)
        self.layout2.addWidget(self.connect_button)
        self.layout2.addWidget(self.ashost_button)
        # 布局
        self.layout = QVBoxLayout()
        self.layout.addLayout(self.layout0)
        self.layout.addLayout(self.layout1)
        self.layout.addLayout(self.layout2)
        self.setLayout(self.layout)
    '''作为客户端'''
    def becomeClient(self):
        self.close()
        self.nickname = self.nickname_edit.text()
        self.target_ip = self.ip_edit.text()
        self.client_ui = gobangClient(cfg=self.cfg, nickname=self.nickname, server_ip=self.target_ip)
        self.client_ui.exit_signal.connect(lambda: sys.exit())
        self.client_ui.back_signal.connect(self.home_ui.show)
        self.client_ui.show()
    '''作为服务器'''
    def becomeHost(self):
        self.close()
        self.nickname = self.nickname_edit.text()
        self.server_ui = gobangSever(cfg=self.cfg, nickname=self.nickname)
        self.server_ui.exit_signal.connect(lambda: sys.exit())
        self.server_ui.back_signal.connect(self.home_ui.show)
        self.server_ui.show()

​如下联机对战界面第一步:

​​

​​

定义五子棋AI算法:


import random
from itertools import product
 
 
'''五子棋AI算法'''
class aiGobang():
    def __init__(self, ai_color, player_color, search_depth=1, **kwargs):
        assert search_depth % 2, 'search_depth must be odd number'
        self.ai_color = ai_color
        self.player_color = player_color
        self.search_depth = search_depth
        self.score_model = [(50, (0, 1, 1, 0, 0)), (50, (0, 0, 1, 1, 0)), (200, (1, 1, 0, 1, 0)),
                            (500, (0, 0, 1, 1, 1)), (500, (1, 1, 1, 0, 0)), (5000, (0, 1, 1, 1, 0)),
                            (5000, (0, 1, 0, 1, 1, 0)), (5000, (0, 1, 1, 0, 1, 0)), (5000, (1, 1, 1, 0, 1)),
                            (5000, (1, 1, 0, 1, 1)), (5000, (1, 0, 1, 1, 1)), (5000, (1, 1, 1, 1, 0)),
                            (5000, (0, 1, 1, 1, 1)), (50000, (0, 1, 1, 1, 1, 0)), (99999999, (1, 1, 1, 1, 1))]
        self.alpha = -99999999
        self.beta = 99999999
        self.all_list = [(i, j) for i, j in product(range(19), range(19))]
    '''外部调用'''
    def act(self, history_record):
        self.ai_list = []
        self.player_list = []
        self.aiplayer_list = []
        for item in history_record:
            self.aiplayer_list.append((item[0], item[1]))
            if item[-1] == self.ai_color:
                self.ai_list.append((item[0], item[1]))
            elif item[-1] == self.player_color:
                self.player_list.append((item[0], item[1]))
        while True:
            self.next_point = random.choice(range(19)), random.choice(range(19))
            if self.next_point not in self.aiplayer_list:
                break
        self.__doSearch(True, self.search_depth, self.alpha, self.beta)
        return self.next_point
    '''负极大值搜索, alpha+beta剪枝'''
    def __doSearch(self, is_ai_round, depth, alpha, beta):
        if self.__isgameover(self.ai_list) or self.__isgameover(self.player_list) or depth == 0:
            return self.__evaluation(is_ai_round)
        blank_list = list(set(self.all_list).difference(set(self.aiplayer_list)))
        blank_list = self.__rearrange(blank_list)
        for next_step in blank_list:
            if not self.__hasNeighbor(next_step):
                continue
            if is_ai_round:
                self.ai_list.append(next_step)
            else:
                self.player_list.append(next_step)
            self.aiplayer_list.append(next_step)
            value = -self.__doSearch(not is_ai_round, depth-1, -beta, -alpha)
            if is_ai_round:
                self.ai_list.remove(next_step)
            else:
                self.player_list.remove(next_step)
            self.aiplayer_list.remove(next_step)
            if value > alpha:
                if depth == self.search_depth:
                    self.next_point = next_step
                if value >= beta:
                    return beta
                alpha = value
        return alpha
    '''游戏是否结束了'''
    def __isgameover(self, oneslist):
        for i, j in product(range(19), range(19)):
            if i < 15 and (i, j) in oneslist and (i+1, j) in oneslist and (i+2, j) in oneslist and (i+3, j) in oneslist and (i+4, j) in oneslist:
                return True
            elif j < 15 and (i, j) in oneslist and (i, j+1) in oneslist and (i, j+2) in oneslist and (i, j+3) in oneslist and (i, j+4) in oneslist:
                return True
            elif i < 15 and j < 15 and (i, j) in oneslist and (i+1, j+1) in oneslist and (i+2, j+2) in oneslist and (i+3, j+3) in oneslist and (i+4, j+4) in oneslist:
                return True
            elif i > 3 and j < 15 and (i, j) in oneslist and (i-1, j+1) in oneslist and (i-2, j+2) in oneslist and (i-3, j+3) in oneslist and (i-4, j+4) in oneslist:
                return True
        return False
    '''重新排列未落子位置'''
    def __rearrange(self, blank_list):
        last_step = self.aiplayer_list[-1]
        for item in blank_list:
            for i, j in product(range(-1, 2), range(-1, 2)):
                if i == 0 and j == 0:
                    continue
                next_step = (last_step[0]+i, last_step[1]+j)
                if next_step in blank_list:
                    blank_list.remove(next_step)
                    blank_list.insert(0, next_step)
        return blank_list
    '''是否存在近邻'''
    def __hasNeighbor(self, next_step):
        for i, j in product(range(-1, 2), range(-1, 2)):
            if i == 0 and j == 0:
                continue
            if (next_step[0]+i, next_step[1]+j) in self.aiplayer_list:
                return True
        return False
    '''计算得分'''
    def __calcScore(self, i, j, x_direction, y_direction, list1, list2, all_scores):
        add_score = 0
        max_score = (0, None)
        for each in all_scores:
            for item in each[1]:
                if i == item[0] and j == item[1] and x_direction == each[2][0] and y_direction == each[2][1]:
                    return 0, all_scores
        for noffset in range(-5, 1):
            position = []
            for poffset in range(6):
                x, y = i + (poffset + noffset) * x_direction, j + (poffset + noffset) * y_direction
                if (x, y) in list2:
                    position.append(2)
                elif (x, y) in list1:
                    position.append(1)
                else:
                    position.append(0)
            shape_len5 = tuple(position[0: -1])
            shape_len6 = tuple(position)
            for score, shape in self.score_model:
                if shape_len5 == shape or shape_len6 == shape:
                    if score > max_score[0]:
                        max_score = (score, ((i + (0 + noffset) * x_direction, j + (0 + noffset) * y_direction),
                                             (i + (1 + noffset) * x_direction, j + (1 + noffset) * y_direction),
                                             (i + (2 + noffset) * x_direction, j + (2 + noffset) * y_direction),
                                             (i + (3 + noffset) * x_direction, j + (3 + noffset) * y_direction),
                                             (i + (4 + noffset) * x_direction, j + (4 + noffset) * y_direction)), (x_direction, y_direction))
        if max_score[1] is not None:
            for each in all_scores:
                for p1 in each[1]:
                    for p2 in max_score[1]:
                        if p1 == p2 and max_score[0] > 10 and each[0] > 10:
                            add_score += max_score[0] + each[0]
            all_scores.append(max_score)
        return add_score+max_score[0], all_scores
    '''评估函数'''
    def __evaluation(self, is_ai_round):
        if is_ai_round:
            list1 = self.ai_list
            list2 = self.player_list
        else:
            list2 = self.ai_list
            list1 = self.player_list
        active_all_scores = []
        active_score = 0
        for item in list1:
            score, active_all_scores = self.__calcScore(item[0], item[1], 0, 1, list1, list2, active_all_scores)
            active_score += score
            score, active_all_scores = self.__calcScore(item[0], item[1], 1, 0, list1, list2, active_all_scores)
            active_score += score
            score, active_all_scores = self.__calcScore(item[0], item[1], 1, 1, list1, list2, active_all_scores)
            active_score += score
            score, active_all_scores = self.__calcScore(item[0], item[1], -1, 1, list1, list2, active_all_scores)
            active_score += score
        passive_all_scores = []
        passive_score = 0
        for item in list2:
            score, passive_all_scores = self.__calcScore(item[0], item[1], 0, 1, list2, list1, passive_all_scores)
            passive_score += score
            score, passive_all_scores = self.__calcScore(item[0], item[1], 1, 0, list2, list1, passive_all_scores)
            passive_score += score
            score, passive_all_scores = self.__calcScore(item[0], item[1], 1, 1, list2, list1, passive_all_scores)
            passive_score += score
            score, passive_all_scores = self.__calcScore(item[0], item[1], -1, 1, list2, list1, passive_all_scores)
            passive_score += score
        total_score = active_score - passive_score * 0.1
        return total_score

总结

好啦!五子棋现在人机对战也可,真人局域网联机也可!文章就到这里​

图片

到此这篇关于python游戏实战项目之智能五子棋的文章就介绍到这了,更多相关python 五子棋内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python游戏实战项目之智能五子棋

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python:游戏:五子棋之人机对战

本文代码基于 python3.6 和 pygame1.9.4。五子棋比起我之前写的几款游戏来说,难度提高了不少。如果是人与人对战,那么,电脑只需要判断是否赢了就可以。如果是人机对战,那你还得让电脑知道怎么下。我们先从简单的问题来看。开端画棋
2023-01-30

python怎么实现人人对战的五子棋游戏

这篇文章主要介绍“python怎么实现人人对战的五子棋游戏”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python怎么实现人人对战的五子棋游戏”文章能帮助大家解决问题。checkerboard.p
2023-06-30

python游戏项目:39行代码打造另类五子棋

前言freegames是Apache2许可的免费Python游戏集合,旨在用于教育和娱乐,完全是开源的,我们只要引用编写就好,专门为游戏而生那今天为大家介绍的是一款另类五子棋,虽然游戏规则跟五子棋的规则是一样的,但是这款游戏是由图形界面来生
2023-06-02

Python+Pygame实现彩色五子棋游戏

这篇文章主要为大家详细介绍了如何溧阳Python和Pygame实现彩色五子棋游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
2023-02-10

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录